library(tidyverse)
library(scales)
library(plotly)
library(lubridate)
Beds
beds <- read_csv("raw_data/non_covid_raw_data/beds_by_nhs_board_of_treatment_and_specialty.csv") %>% janitor::clean_names()
Warning: One or more parsing issues, see `problems()` for detailsRows: 30458 Columns: 20── Column specification ──────────────────────────────────────────────────
Delimiter: ","
chr (10): Quarter, QuarterQF, HB, HBQF, Location, LocationQF, Specialt...
dbl (5): AllStaffedBeddays, TotalOccupiedBeddays, AverageAvailableSta...
lgl (5): AllStaffedBeddaysQF, TotalOccupiedBeddaysQF, AverageAvailabl...
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
beds %>%
filter(specialty_name == "All Acute") %>%
ggplot(aes(x = quarter, y = percentage_occupancy))+
geom_line(aes(colour = hb), group = 1)+
facet_wrap(~ hb)

beds <- beds %>%
select(-c(2,4,6,8,10,12,14,16,18,20)) %>%
filter(!hb %in% c("SB0801", "S92000003"))
beds <- beds %>%
filter(!hb %in% c("SB0801", "S92000003")) %>%
filter(hb == location)
# beds %>%
# count(specialty_name)
a_e_beds <- beds %>%
filter(specialty_name == "Accident & Emergency")
# a&e percentage occupancy by hb over time
a_e_beds %>%
group_by(quarter, hb) %>%
summarise(mean_perc_occ = mean(percentage_occupancy, na.rm = TRUE)) %>%
ggplot(aes(x = quarter, y = mean_perc_occ))+
geom_line(aes(group = hb, colour = hb))+
geom_point()+
theme(axis.text.x = element_text(angle = 45))
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

a_e_beds %>%
count(hb)
#all time bed occupancy percentage for health boards
a_e_beds %>%
group_by(quarter, hb) %>%
summarise(mean_perc_occ = mean(percentage_occupancy, na.rm = TRUE)) %>%
ungroup() %>%
group_by(hb) %>%
summarise(avg_per_occ_all_time = mean(mean_perc_occ)) %>%
arrange(desc(avg_per_occ_all_time)) %>%
ggplot(aes(x = hb, y = avg_per_occ_all_time))+
geom_col()+
geom_point()+
theme(axis.text.x = element_text(angle = 45))
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

# workout the ten largest
ten_largest_specialities <- beds %>%
group_by(specialty_name) %>%
summarise(mean_avail_staffed_beds = mean(average_available_staffed_beds)) %>%
arrange(desc(mean_avail_staffed_beds)) %>%
slice_max(mean_avail_staffed_beds, n=10) %>%
select(1) %>%
pull()
# bed percentage availablity for top ten largest specialities
beds %>%
filter(specialty_name %in% ten_largest_specialities) %>%
group_by(quarter, specialty_name) %>%
summarise(mean_perc_occ = mean(percentage_occupancy)) %>%
ggplot(aes(x = quarter, y = mean_perc_occ))+
geom_line(aes(colour = specialty_name, group = specialty_name))+
geom_point()+
theme(axis.text.x = element_text(angle = 45, hjust = 1))
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

# bed percentage availablity for all acute
beds %>%
filter(specialty_name == "All Acute") %>%
group_by(quarter, specialty_name) %>%
summarise(mean_perc_occ = mean(percentage_occupancy)) %>%
ggplot(aes(x = quarter, y = mean_perc_occ))+
geom_line(aes(colour = specialty_name, group = specialty_name))+
geom_point()+
theme(axis.text.x = element_text(angle = 45, hjust = 1))
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

# bed percentage availability for intensive care
beds %>%
filter(specialty_name == "Intensive Care Medicine") %>%
group_by(quarter, specialty_name) %>%
summarise(mean_perc_occ = mean(percentage_occupancy)) %>%
ggplot(aes(x = quarter, y = mean_perc_occ))+
geom_line(aes(colour = specialty_name, group = specialty_name))+
geom_point()+
theme(axis.text.x = element_text(angle = 45, hjust = 1))
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

NA
NA
NA
a_e_beds %>%
group_by(quarter) %>%
summarise(mean_available_beds = mean(average_available_staffed_beds, na.rm = TRUE)) %>%
ggplot(aes(x = quarter, y = mean_available_beds))+
geom_line(group ="1")+
geom_point()+
theme(axis.text.x = element_text(angle = 45))

age sex
age_sex <- read_csv("raw_data/non_covid_raw_data/inpatient_and_daycase_by_nhs_board_of_treatment_age_and_sex.csv") %>% janitor::clean_names()
Rows: 129393 Columns: 18── Column specification ──────────────────────────────────────────────────
Delimiter: ","
chr (12): Quarter, QuarterQF, HB, HBQF, Location, LocationQF, Admissio...
dbl (6): Episodes, LengthOfEpisode, AverageLengthOfEpisode, Stays, Le...
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
health_board_names <- read_csv("raw_data/non_covid_raw_data/health_board_names.csv")
Rows: 18 Columns: 5── Column specification ──────────────────────────────────────────────────
Delimiter: ","
chr (3): HB, HBName, Country
dbl (2): HBDateEnacted, HBDateArchived
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
age_sex %>%
count(hb)
season_age_sex <- age_sex %>%
mutate(date = yq(quarter),
year = year(date),
month = month(date, label = TRUE, abbr = FALSE),
season = case_when(
str_detect(month, "December") ~ "Winter",
str_detect(month, "January") ~ "Winter",
str_detect(month, "February") ~ "Winter",
str_detect(month, "March") ~ "Spring",
str_detect(month, "April") ~ "Spring",
str_detect(month, "May") ~ "Spring",
str_detect(month, "June") ~ "Summer",
str_detect(month, "July") ~ "Summer",
str_detect(month, "August") ~ "Summer",
str_detect(month, "September") ~ "Autumn",
str_detect(month, "October") ~ "Autumn",
str_detect(month, "November") ~ "Autumn"),
season = factor(season, order = TRUE))
library(lubridate)
library(zoo)
Attaching package: ‘zoo’
The following objects are masked from ‘package:base’:
as.Date, as.Date.numeric
# change quarter column into the date at the start of each quarter
age_sex <- age_sex %>%
mutate(quarter = yq(quarter))
# shows the total length of stay by age bracket for emergency inpatients
age_sex %>%
filter(admission_type == "Emergency Inpatients") %>%
group_by(quarter, age) %>%
summarise(total_length_of_stay = sum(length_of_stay)) %>%
ggplot(aes(x = quarter, y = total_length_of_stay))+
geom_line(aes(colour = age))+
theme(axis.text.x = element_text(angle = 45))
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

age_sex %>%
count(admission_type)
age_sex
# shows the total length of stay by age bracket for elective inpatients
age_sex %>%
filter(admission_type == "Elective Inpatients") %>%
group_by(quarter, age) %>%
summarise(total_length_of_stay = sum(length_of_stay)) %>%
ggplot(aes(x = quarter, y = total_length_of_stay))+
geom_line(aes(colour = age))+
theme(axis.text.x = element_text(angle = 45))
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

# shows the mean length of stay by age bracket for emergency inpatients
#can facet by sex also if required
age_sex %>%
filter(admission_type == "Emergency Inpatients") %>%
group_by(quarter, age) %>%
summarise(avg_length_of_stay = mean(average_length_of_stay, na.rm = TRUE)) %>%
ggplot(aes(x = quarter, y = avg_length_of_stay))+
geom_line(aes(colour = age, group = age))+
theme(axis.text.x = element_text(angle = 45))
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

#facet_wrap( ~ sex)
# shows the mean length of stay by age bracket for elective inpatients
# can facet by sex
age_sex %>%
filter(admission_type == "Elective Inpatients") %>%
group_by(quarter, age) %>%
summarise(avg_length_of_stay = mean(average_length_of_stay, na.rm = TRUE)) %>%
ggplot(aes(x = quarter, y = avg_length_of_stay))+
geom_line(aes(colour = age, group = age))+
theme(axis.text.x = element_text(angle = 45))
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

# #facet_wrap(~ sex)
age_sex %>%
mutate(date = yq(quarter),
year = year(date),
month = month(date, label = TRUE, abbr = FALSE),
season = case_when(
str_detect(month, "December") ~ "Winter",
str_detect(month, "January") ~ "Winter",
str_detect(month, "February") ~ "Winter",
str_detect(month, "March") ~ "Spring",
str_detect(month, "April") ~ "Spring",
str_detect(month, "May") ~ "Spring",
str_detect(month, "June") ~ "Summer",
str_detect(month, "July") ~ "Summer",
str_detect(month, "August") ~ "Summer",
str_detect(month, "September") ~ "Autumn",
str_detect(month, "October") ~ "Autumn",
str_detect(month, "November") ~ "Autumn"),
season = factor(season, order = TRUE))
Warning: All formats failed to parse. No formats found.
age_sex %>%
filter(admission_type == "Emergency Inpatients") %>%
group_by(quarter, sex) %>%
summarise(avg_length_of_stay = mean(average_length_of_stay, na.rm = TRUE)) %>%
ggplot(aes(x = quarter, y = avg_length_of_stay))+
geom_line(aes(colour = sex, group = sex))+
theme(axis.text.x = element_text(angle = 45))+
geom_smooth(aes(colour = sex, group = sex), se = FALSE)+
geom_point(aes(colour = sex), size = 0.5)+
labs(title = "Emergency Inpatient by gender and average length of stay")
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

age_sex %>%
filter(admission_type == "Elective Inpatients") %>%
group_by(quarter, sex) %>%
summarise(avg_length_of_stay = mean(average_length_of_stay, na.rm = TRUE)) %>%
ggplot(aes(x = quarter, y = avg_length_of_stay))+
geom_line(aes(colour = sex, group = sex))+
theme(axis.text.x = element_text(angle = 45))+
geom_smooth(aes(colour = sex, group = sex), se = FALSE)+
geom_point(aes(colour = sex), size = 0.5)+
labs(title = "Elective Inpatient by gender and average length of stay")
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

# emergency inpatient by age and avg length of stay
age_sex %>%
filter(admission_type == "Emergency Inpatients") %>%
group_by(quarter, age) %>%
summarise(avg_length_of_stay = mean(average_length_of_stay, na.rm = TRUE)) %>%
ggplot(aes(x = quarter, y = avg_length_of_stay))+
geom_line(aes(colour = age, group = age))+
theme(axis.text.x = element_text(angle = 45))+
#geom_smooth(aes(colour = sex, group = sex), se = FALSE)+
geom_point(aes(colour = age), size = 0.5)+
labs(title = "Emergency inpatient by age and avg length of stay")
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

# elective inpatient by age and avg length of stay
age_sex %>%
filter(admission_type == "Elective Inpatients") %>%
group_by(quarter, age) %>%
summarise(avg_length_of_stay = mean(average_length_of_stay, na.rm = TRUE)) %>%
ggplot(aes(x = quarter, y = avg_length_of_stay))+
geom_line(aes(colour = age, group = age))+
theme(axis.text.x = element_text(angle = 45))+
#geom_smooth(aes(colour = sex, group = sex), se = FALSE)+
geom_point(aes(colour = age), size = 0.5)+
labs(title = "Elective inpatient by age and avg length of stay")
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

# emergency inpatient by age and avg length of epsiode
age_sex %>%
filter(admission_type == "Emergency Inpatients") %>%
group_by(quarter, age) %>%
summarise(avg_length_of_episode = mean(average_length_of_episode, na.arm = TRUE)) %>%
ggplot(aes(x = quarter, y = avg_length_of_episode))+
geom_line(aes(colour = age, group = age))+
theme(axis.text.x = element_text(angle = 45))+
#geom_smooth(aes(colour = sex, group = sex), se = FALSE)+
geom_point(aes(colour = age), size = 0.5)+
labs(title = "Emergency inpatient by age and avg length of episode")
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

# elective inpatient by age and avg length of episode
age_sex %>%
filter(admission_type == "Elective Inpatients") %>%
group_by(quarter, age) %>%
summarise(avg_length_of_episode = mean(average_length_of_episode, na.rm = TRUE)) %>%
ggplot(aes(x = quarter, y = avg_length_of_episode))+
geom_line(aes(colour = age, group = age))+
theme(axis.text.x = element_text(angle = 45))+
#geom_smooth(aes(colour = sex, group = sex), se = FALSE)+
geom_point(aes(colour = age), size = 0.5)+
labs(title = "Elective inpatient by age and avg length of episode")
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

# emergency inpatient by age and avg episodes
age_sex %>%
filter(admission_type == "Emergency Inpatients") %>%
group_by(quarter, age) %>%
summarise(avg_episodes = mean(episodes, na.rm = TRUE)) %>%
ggplot(aes(x = quarter, y = avg_episodes))+
geom_line(aes(colour = age, group = age))+
theme(axis.text.x = element_text(angle = 45))+
#geom_smooth(aes(colour = sex, group = sex), se = FALSE)+
geom_point(aes(colour = age), size = 0.5)+
labs(title = "Emergency inpatient by age and avg episodes")
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

# emergency inpatient by age and avg episodes
age_sex %>%
filter(admission_type == "Elective Inpatients") %>%
group_by(quarter, age) %>%
summarise(avg_episodes = mean(episodes, na.rm = TRUE)) %>%
ggplot(aes(x = quarter, y = avg_episodes))+
geom_line(aes(colour = age, group = age))+
theme(axis.text.x = element_text(angle = 45))+
#geom_smooth(aes(colour = sex, group = sex), se = FALSE)+
geom_point(aes(colour = age), size = 0.5)+
labs(title = "Elective inpatient by age and avg episodes")
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

# Plot comparison of Emergency vs Elective submissions
age_sex %>%
filter(admission_type %in% c("Emergency Inpatients", "Elective Inpatients")) %>%
group_by(quarter, admission_type) %>%
summarise(avg_stay = mean(average_length_of_stay, na.rm = TRUE)) %>%
ggplot(aes(x = quarter, y = avg_stay, colour = admission_type))+
geom_line(aes(group = admission_type))+
geom_point()+
theme(axis.text.x = element_text(angle = 45, hjust = 1))
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

# avg_stay by admission type
age_sex %>%
group_by(quarter, admission_type) %>%
summarise(avg_stay = mean(average_length_of_stay, na.rm = TRUE)) %>%
ggplot(aes(x = quarter, y = avg_stay, colour = admission_type))+
geom_line(aes(group = admission_type))+
geom_point()+
theme(axis.text.x = element_text(angle = 45, hjust = 1))
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

# avg_stay for all types
age_sex %>%
group_by(quarter) %>%
summarise(avg_stay = mean(average_length_of_stay, na.rm = TRUE)) %>%
ggplot(aes(x = quarter, y = avg_stay, group = 1))+
geom_line(aes(group = 1))+
geom_point()+
theme(axis.text.x = element_text(angle = 45, hjust = 1))

# number of stays for all types
age_sex %>%
group_by(quarter) %>%
summarise(total_stays = sum(stays, na.rm = TRUE)) %>%
ggplot(aes(x = quarter, y = total_stays, group = 1))+
geom_line(aes(group = 1))+
geom_point()+
theme(axis.text.x = element_text(angle = 45, hjust = 1))

SIMD
simd <- read_csv("raw_data/non_covid_raw_data/inpatient_and_daycase_by_nhs_board_of_treatment_and_simd.csv") %>% janitor::clean_names()
Rows: 40821 Columns: 18── Column specification ──────────────────────────────────────────────────
Delimiter: ","
chr (11): Quarter, QuarterQF, HB, HBQF, Location, LocationQF, Admissio...
dbl (7): SIMD, Episodes, LengthOfEpisode, AverageLengthOfEpisode, Sta...
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
#total episodes(hospitalisations?) by simd value
simd %>%
drop_na(simd) %>%
mutate(simd = as.factor(simd)) %>% # gives each simd a separate colour
group_by(quarter, simd) %>%
summarise(total_episodes = sum(episodes, na.rm = TRUE)) %>%
ggplot(aes(x = quarter, y = total_episodes, group = simd))+
geom_line(aes(colour = simd))+
theme(axis.text.x = element_text(angle = 45, hjust = 1))+
scale_y_continuous(labels = scales::comma)
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

#avg number of episodes(hospitalisations?) by simd value
simd %>%
drop_na(simd) %>%
mutate(simd = as.factor(simd)) %>% # gives each simd a separate colour
group_by(quarter, simd) %>%
summarise(avg_episodes = mean(episodes, na.rm = TRUE)) %>%
ggplot(aes(x = quarter, y = avg_episodes, group = simd))+
geom_line(aes(colour = simd))+
theme(axis.text.x = element_text(angle = 45, hjust = 1))+
scale_y_continuous(labels = scales::comma)
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

#avg stays by simd value
simd %>%
drop_na(simd) %>%
mutate(simd = as.factor(simd)) %>% # gives each simd a separate colour
group_by(quarter, simd) %>%
summarise(avg_stays = mean(stays, na.rm = TRUE)) %>%
ggplot(aes(x = quarter, y = avg_stays, group = simd))+
geom_line(aes(colour = simd))+
theme(axis.text.x = element_text(angle = 45, hjust = 1))+
scale_y_continuous(labels = scales::comma)
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

NA
#total episodes(hospitalisations?) by simd value
simd %>%
drop_na(simd) %>%
filter(admission_type == "Emergency Inpatients") %>%
mutate(simd = as.factor(simd)) %>% # gives each simd a separate colour
group_by(quarter, simd) %>%
summarise(total_episodes = sum(episodes, na.rm = TRUE)) %>%
ggplot(aes(x = quarter, y = total_episodes, group = simd))+
geom_line(aes(colour = simd))+
theme(axis.text.x = element_text(angle = 45, hjust = 1))+
scale_y_continuous(labels = scales::comma)
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

#avg number of episodes(hospitalisations?) by simd value
simd %>%
drop_na(simd) %>%
filter(admission_type == "Emergency Inpatients") %>%
mutate(simd = as.factor(simd)) %>% # gives each simd a separate colour
group_by(quarter, simd) %>%
summarise(avg_episodes = mean(episodes, na.rm = TRUE)) %>%
ggplot(aes(x = quarter, y = avg_episodes, group = simd))+
geom_line(aes(colour = simd))+
theme(axis.text.x = element_text(angle = 45, hjust = 1))+
scale_y_continuous(labels = scales::comma)
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

#avg stays by simd value
simd %>%
drop_na(simd) %>%
filter(admission_type == "Emergency Inpatients") %>%
mutate(simd = as.factor(simd)) %>% # gives each simd a separate colour
group_by(quarter, simd) %>%
summarise(avg_stays = mean(stays, na.rm = TRUE)) %>%
ggplot(aes(x = quarter, y = avg_stays, group = simd))+
geom_line(aes(colour = simd))+
theme(axis.text.x = element_text(angle = 45, hjust = 1))+
scale_y_continuous(labels = scales::comma)
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

NA
NA
# plot avg stay length for most and least deprived for emergency unpatients
simd %>%
filter(admission_type == "Emergency Inpatients", simd %in% c(1,5)) %>%
drop_na(simd) %>%
group_by(quarter,simd) %>%
summarise(avg_stay_length = mean(average_length_of_stay, na.rm = TRUE)) %>%
ggplot(aes(x = quarter, y = avg_stay_length)) +
geom_line(aes(colour = simd, group = simd))+
theme(axis.text.x = element_text(angle = 45, hjust = 1))
`summarise()` has grouped output by 'quarter'. You can override using the `.groups` argument.

NA
speciality <- read_csv("raw_data/non_covid_raw_data/inpatient_and_daycase_by_nhs_board_of_treatment_and_specialty.csv") %>% janitor::clean_names()
Rows: 95270 Columns: 18── Column specification ──────────────────────────────────────────────────
Delimiter: ","
chr (12): Quarter, QuarterQF, HB, HBQF, Location, LocationQF, Admissio...
dbl (6): Episodes, LengthOfEpisode, AverageLengthOfEpisode, Spells, L...
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
speciality %>%
count(admission_type)
speciality %>%
count(hb)
speciality %>%
count(location)
speciality %>%
count(specialty_name)
# add averages
speciality_averages <- speciality %>%
group_by(quarter, admission_type) %>%
mutate(avg_length_spell= mean(average_length_of_spell, na.rm = TRUE),
avg_length_episode = mean(average_length_of_episode, na.rm = TRUE)) %>%
ungroup()
speciality_averages %>%
group_by(quarter, admission_type) %>%
slice(1) %>%
ggplot(aes(x = quarter, y = average_length_of_episode, group = admission_type)) +
geom_line(aes(colour = admission_type))+
theme(axis.text.x = element_text(angle = 45, hjust = 1))

ae_wait_times <- read_csv("raw_data/non_covid_raw_data/monthly_ae_waitingtimes_202206.csv") %>% janitor::clean_names()
Rows: 15837 Columns: 25── Column specification ──────────────────────────────────────────────────
Delimiter: ","
chr (13): Country, HBT, TreatmentLocation, DepartmentType, NumberOfAtt...
dbl (12): Month, NumberOfAttendancesAggregate, NumberOfAttendancesEpis...
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
#glimpse(ae_wait_times)
#make a date and year column with the first date of every month
ae_wait_times <- ae_wait_times %>%
mutate(date = ym(month), .after = month,
year = year(date))
#make a percent column with percent of patients meeting the 4hr target time
ae_wait_times <- ae_wait_times %>%
mutate(percent_4hr_target_achieved = (number_meeting_target_aggregate/number_of_attendances_aggregate)*100) %>%
#add an 8hr one - not currently used
mutate(percent_seen_within_8hr = ((number_of_attendances_aggregate-attendance_greater8hrs)/number_of_attendances_aggregate)*100)
# draw percentage of 4 hour wait for all years
for_plotly <- ae_wait_times %>%
filter(department_type == "Emergency Department") %>%
group_by(date, department_type) %>%
summarise(avg_4hr_target_made = mean(percent_4hr_target_achieved)) %>%
ggplot(aes(x = date, y = avg_4hr_target_made))+
geom_line(aes(colour = department_type))+
scale_x_date(date_breaks = "6 months", date_labels = "%b %Y")+
theme(axis.text.x = element_text(angle = 90, hjust = 1, size =7))+
geom_smooth()+
geom_vline(xintercept = as.numeric(as.Date("2008-01-01")), linetype=4)+
geom_vline(xintercept = as.numeric(as.Date("2009-01-01")), linetype=4)+
geom_vline(xintercept = as.numeric(as.Date("2010-01-01")), linetype=4)+
geom_vline(xintercept = as.numeric(as.Date("2011-01-01")), linetype=4)+
geom_vline(xintercept = as.numeric(as.Date("2012-01-01")), linetype=4)+
geom_vline(xintercept = as.numeric(as.Date("2013-01-01")), linetype=4)+
geom_vline(xintercept = as.numeric(as.Date("2014-01-01")), linetype=4)+
geom_vline(xintercept = as.numeric(as.Date("2015-01-01")), linetype=4)+
geom_vline(xintercept = as.numeric(as.Date("2016-01-01")), linetype=4)+
geom_vline(xintercept = as.numeric(as.Date("2017-01-01")), linetype=4)+
geom_vline(xintercept = as.numeric(as.Date("2018-01-01")), linetype=4)+
geom_vline(xintercept = as.numeric(as.Date("2019-01-01")), linetype=4)+
geom_vline(xintercept = as.numeric(as.Date("2020-01-01")), linetype=4)+
labs(title = "percentage of A&E departments meeting the 4 hr target turnaround for patients",
subtitle = "added in vertical lines for January to help")
`summarise()` has grouped output by 'date'. You can override using the `.groups` argument.
ggplotly(for_plotly)
`geom_smooth()` using method = 'loess' and formula 'y ~ x'
Warning: `gather_()` was deprecated in tidyr 1.2.0.
Please use `gather()` instead.
# 4hr wait by health board for all years facet wrapped
ae_wait_times %>%
filter(department_type == "Emergency Department") %>%
group_by(date, hbt) %>%
mutate(avg_4hr_target_made = mean(percent_4hr_target_achieved)) %>%
slice(1) %>%
ggplot(aes(x = date, y = avg_4hr_target_made))+
geom_line(aes(colour = hbt))+
scale_x_date(date_breaks = "6 months", date_labels = "%b %Y")+
theme(axis.text.x = element_text(angle = 90, hjust = 1, size =7))+
geom_smooth()+
geom_vline(xintercept = as.numeric(as.Date("2008-01-01")), linetype=4)+
geom_vline(xintercept = as.numeric(as.Date("2009-01-01")), linetype=4)+
geom_vline(xintercept = as.numeric(as.Date("2010-01-01")), linetype=4)+
geom_vline(xintercept = as.numeric(as.Date("2011-01-01")), linetype=4)+
geom_vline(xintercept = as.numeric(as.Date("2012-01-01")), linetype=4)+
geom_vline(xintercept = as.numeric(as.Date("2013-01-01")), linetype=4)+
geom_vline(xintercept = as.numeric(as.Date("2014-01-01")), linetype=4)+
geom_vline(xintercept = as.numeric(as.Date("2015-01-01")), linetype=4)+
geom_vline(xintercept = as.numeric(as.Date("2016-01-01")), linetype=4)+
geom_vline(xintercept = as.numeric(as.Date("2017-01-01")), linetype=4)+
geom_vline(xintercept = as.numeric(as.Date("2018-01-01")), linetype=4)+
geom_vline(xintercept = as.numeric(as.Date("2019-01-01")), linetype=4)+
facet_wrap(~ hbt)

target_2007 <- ae_wait_times %>%
group_by(year, hbt) %>%
summarise(ae_4hr_target_achieved = mean(percent_4hr_target_achieved, na.rm = TRUE)) %>%
filter(year == 2007) %>%
rename(ae_target_2007 = ae_4hr_target_achieved) %>%
ungroup() %>%
select(hbt,ae_target_2007)
`summarise()` has grouped output by 'year'. You can override using the `.groups` argument.
target_2008 <- ae_wait_times %>%
group_by(year, hbt) %>%
summarise(ae_4hr_target_achieved = mean(percent_4hr_target_achieved, na.rm = TRUE)) %>%
filter(year == 2008) %>%
rename(ae_target_2008 = ae_4hr_target_achieved) %>%
ungroup() %>%
select(hbt,ae_target_2008)
`summarise()` has grouped output by 'year'. You can override using the `.groups` argument.
target_2009 <- ae_wait_times %>%
group_by(year, hbt) %>%
summarise(ae_4hr_target_achieved = mean(percent_4hr_target_achieved, na.rm = TRUE)) %>%
filter(year == 2009) %>%
rename(ae_target_2009 = ae_4hr_target_achieved) %>%
ungroup() %>%
select(hbt,ae_target_2009)
`summarise()` has grouped output by 'year'. You can override using the `.groups` argument.
target_2010 <- ae_wait_times %>%
group_by(year, hbt) %>%
summarise(ae_4hr_target_achieved = mean(percent_4hr_target_achieved, na.rm = TRUE)) %>%
filter(year == 2010) %>%
rename(ae_target_2010 = ae_4hr_target_achieved) %>%
ungroup() %>%
select(hbt,ae_target_2010)
`summarise()` has grouped output by 'year'. You can override using the `.groups` argument.
target_2011 <- ae_wait_times %>%
group_by(year, hbt) %>%
summarise(ae_4hr_target_achieved = mean(percent_4hr_target_achieved, na.rm = TRUE)) %>%
filter(year == 2011) %>%
rename(ae_target_2011 = ae_4hr_target_achieved) %>%
ungroup() %>%
select(hbt,ae_target_2011)
`summarise()` has grouped output by 'year'. You can override using the `.groups` argument.
target_2012 <- ae_wait_times %>%
group_by(year, hbt) %>%
summarise(ae_4hr_target_achieved = mean(percent_4hr_target_achieved, na.rm = TRUE)) %>%
filter(year == 2012) %>%
rename(ae_target_2012 = ae_4hr_target_achieved) %>%
ungroup() %>%
select(hbt,ae_target_2012)
`summarise()` has grouped output by 'year'. You can override using the `.groups` argument.
target_2013 <- ae_wait_times %>%
group_by(year, hbt) %>%
summarise(ae_4hr_target_achieved = mean(percent_4hr_target_achieved, na.rm = TRUE)) %>%
filter(year == 2013) %>%
rename(ae_target_2013 = ae_4hr_target_achieved) %>%
ungroup() %>%
select(hbt,ae_target_2013)
`summarise()` has grouped output by 'year'. You can override using the `.groups` argument.
target_2014 <- ae_wait_times %>%
group_by(year, hbt) %>%
summarise(ae_4hr_target_achieved = mean(percent_4hr_target_achieved, na.rm = TRUE)) %>%
filter(year == 2014) %>%
rename(ae_target_2014 = ae_4hr_target_achieved) %>%
ungroup() %>%
select(hbt,ae_target_2014)
`summarise()` has grouped output by 'year'. You can override using the `.groups` argument.
target_2015 <- ae_wait_times %>%
group_by(year, hbt) %>%
summarise(ae_4hr_target_achieved = mean(percent_4hr_target_achieved, na.rm = TRUE)) %>%
filter(year == 2015) %>%
rename(ae_target_2015 = ae_4hr_target_achieved) %>%
ungroup() %>%
select(hbt,ae_target_2015)
`summarise()` has grouped output by 'year'. You can override using the `.groups` argument.
target_2016 <- ae_wait_times %>%
group_by(year, hbt) %>%
summarise(ae_4hr_target_achieved = mean(percent_4hr_target_achieved, na.rm = TRUE)) %>%
filter(year == 2016) %>%
rename(ae_target_2016 = ae_4hr_target_achieved) %>%
ungroup() %>%
select(hbt,ae_target_2016)
`summarise()` has grouped output by 'year'. You can override using the `.groups` argument.
target_2017 <- ae_wait_times %>%
group_by(year, hbt) %>%
summarise(ae_4hr_target_achieved = mean(percent_4hr_target_achieved, na.rm = TRUE)) %>%
filter(year == 2017) %>%
rename(ae_target_2017 = ae_4hr_target_achieved) %>%
ungroup() %>%
select(hbt,ae_target_2017)
`summarise()` has grouped output by 'year'. You can override using the `.groups` argument.
target_2018 <- ae_wait_times %>%
group_by(year, hbt) %>%
summarise(ae_4hr_target_achieved = mean(percent_4hr_target_achieved, na.rm = TRUE)) %>%
filter(year == 2018) %>%
rename(ae_target_2018 = ae_4hr_target_achieved) %>%
ungroup() %>%
select(hbt,ae_target_2018)
`summarise()` has grouped output by 'year'. You can override using the `.groups` argument.
target_2019 <- ae_wait_times %>%
group_by(year, hbt) %>%
summarise(ae_4hr_target_achieved = mean(percent_4hr_target_achieved, na.rm = TRUE)) %>%
filter(year == 2019) %>%
rename(ae_target_2019 = ae_4hr_target_achieved) %>%
ungroup() %>%
select(hbt,ae_target_2019)
`summarise()` has grouped output by 'year'. You can override using the `.groups` argument.
target_2020 <- ae_wait_times %>%
group_by(year, hbt) %>%
summarise(ae_4hr_target_achieved = mean(percent_4hr_target_achieved, na.rm = TRUE)) %>%
filter(year == 2020) %>%
rename(ae_target_2020 = ae_4hr_target_achieved) %>%
ungroup() %>%
select(hbt,ae_target_2020)
`summarise()` has grouped output by 'year'. You can override using the `.groups` argument.
target_2021 <- ae_wait_times %>%
group_by(year, hbt) %>%
summarise(ae_4hr_target_achieved = mean(percent_4hr_target_achieved, na.rm = TRUE)) %>%
filter(year == 2021) %>%
rename(ae_target_2021 = ae_4hr_target_achieved) %>%
ungroup() %>%
select(hbt,ae_target_2021)
`summarise()` has grouped output by 'year'. You can override using the `.groups` argument.
library(sf)
scotland <- st_read("../SG_NHS_HealthBoards_2019_shapefile/SG_NHS_HealthBoards_2019.shp")
Reading layer `SG_NHS_HealthBoards_2019' from data source
`C:\Users\neilp\Documents\CODECLAN\phs_scotland_group_project\SG_NHS_HealthBoards_2019_shapefile\SG_NHS_HealthBoards_2019.shp'
using driver `ESRI Shapefile'
Simple feature collection with 14 features and 4 fields
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: 5512.998 ymin: 530250.8 xmax: 470332 ymax: 1220302
Projected CRS: OSGB 1936 / British National Grid
# view(scotland)
#
head(scotland, 3)
Simple feature collection with 3 features and 4 fields
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: 186130 ymin: 530250.8 xmax: 398017.2 ymax: 672679.8
Projected CRS: OSGB 1936 / British National Grid
HBCode HBName Shape_Leng Shape_Area
1 S08000015 Ayrshire and Arran 679782.3 3408802229
2 S08000016 Borders 525406.7 4742684960
3 S08000017 Dumfries and Galloway 830301.2 6676314851
geometry
1 MULTIPOLYGON (((201916.2 60...
2 MULTIPOLYGON (((345325.9 57...
3 MULTIPOLYGON (((266004.4 54...
#
plot(scotland[-1])

scotland <- scotland %>%
mutate(centres = st_centroid(st_make_valid(geometry))) %>%
mutate(lat = st_coordinates(centres)[,1],
long = st_coordinates(centres)[,2],
target_2007 = target_2007$ae_target_2007,
target_2008 = target_2008$ae_target_2008,
target_2009 = target_2009$ae_target_2009,
target_2010 = target_2010$ae_target_2010,
target_2011 = target_2011$ae_target_2011,
target_2012 = target_2012$ae_target_2012,
target_2013 = target_2013$ae_target_2013,
target_2014 = target_2014$ae_target_2014,
target_2015 = target_2015$ae_target_2015,
target_2016 = target_2016$ae_target_2016,
target_2017 = target_2017$ae_target_2017,
target_2018 = target_2018$ae_target_2018,
target_2019 = target_2019$ae_target_2019,
target_2020 = target_2020$ae_target_2020,
target_2021 = target_2021$ae_target_2021
)
ggplot(data = scotland) +
geom_sf(aes(fill = change_ae)) +
scale_fill_viridis_c(option = "plasma")+
labs(title = "percent change in A&E depts meeting the 4 hour target 2007 - 2018")
LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KYGBge3J9DQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoc2NhbGVzKQ0KbGlicmFyeShwbG90bHkpDQpsaWJyYXJ5KGx1YnJpZGF0ZSkNCmBgYA0KIyBCZWRzDQpgYGB7cn0NCmJlZHMgPC0gcmVhZF9jc3YoInJhd19kYXRhL25vbl9jb3ZpZF9yYXdfZGF0YS9iZWRzX2J5X25oc19ib2FyZF9vZl90cmVhdG1lbnRfYW5kX3NwZWNpYWx0eS5jc3YiKSAlPiUgamFuaXRvcjo6Y2xlYW5fbmFtZXMoKQ0KYGBgDQoNCmBgYHtyfQ0KYmVkcyAlPiUgDQogIGZpbHRlcihzcGVjaWFsdHlfbmFtZSA9PSAiQWxsIEFjdXRlIikgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBxdWFydGVyLCB5ID0gcGVyY2VudGFnZV9vY2N1cGFuY3kpKSsNCiAgZ2VvbV9saW5lKGFlcyhjb2xvdXIgPSBoYiksIGdyb3VwID0gMSkrDQogIGZhY2V0X3dyYXAofiBoYikNCmBgYA0KDQpgYGB7cn0NCmJlZHMgPC0gYmVkcyAlPiUgDQogIHNlbGVjdCgtYygyLDQsNiw4LDEwLDEyLDE0LDE2LDE4LDIwKSkgJT4lIA0KICBmaWx0ZXIoIWhiICVpbiUgYygiU0IwODAxIiwgIlM5MjAwMDAwMyIpKQ0KDQpiZWRzIDwtIGJlZHMgJT4lIA0KICBmaWx0ZXIoIWhiICVpbiUgYygiU0IwODAxIiwgIlM5MjAwMDAwMyIpKSAlPiUgDQogIGZpbHRlcihoYiA9PSBsb2NhdGlvbikNCiAgDQojIGJlZHMgJT4lIA0KIyBjb3VudChzcGVjaWFsdHlfbmFtZSkNCg0KYV9lX2JlZHMgPC0gYmVkcyAlPiUgDQogIGZpbHRlcihzcGVjaWFsdHlfbmFtZSA9PSAiQWNjaWRlbnQgJiBFbWVyZ2VuY3kiKQ0KYGBgDQoNCmBgYHtyfQ0KIyBhJmUgcGVyY2VudGFnZSBvY2N1cGFuY3kgYnkgaGIgb3ZlciB0aW1lDQphX2VfYmVkcyAlPiUgDQogIGdyb3VwX2J5KHF1YXJ0ZXIsIGhiKSAlPiUgDQogIHN1bW1hcmlzZShtZWFuX3BlcmNfb2NjID0gbWVhbihwZXJjZW50YWdlX29jY3VwYW5jeSwgbmEucm0gPSBUUlVFKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBxdWFydGVyLCB5ID0gbWVhbl9wZXJjX29jYykpKw0KICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gaGIsIGNvbG91ciA9IGhiKSkrDQogIGdlb21fcG9pbnQoKSsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSkpDQoNCg0KYV9lX2JlZHMgJT4lIA0KICBjb3VudChoYikNCmBgYA0KDQpgYGB7cn0NCiNhbGwgdGltZSBiZWQgb2NjdXBhbmN5IHBlcmNlbnRhZ2UgZm9yIGhlYWx0aCBib2FyZHMNCmFfZV9iZWRzICU+JSANCiAgZ3JvdXBfYnkocXVhcnRlciwgaGIpICU+JSANCiAgc3VtbWFyaXNlKG1lYW5fcGVyY19vY2MgPSBtZWFuKHBlcmNlbnRhZ2Vfb2NjdXBhbmN5LCBuYS5ybSA9IFRSVUUpKSAlPiUgDQp1bmdyb3VwKCkgJT4lIA0KICBncm91cF9ieShoYikgJT4lIA0KICBzdW1tYXJpc2UoYXZnX3Blcl9vY2NfYWxsX3RpbWUgPSBtZWFuKG1lYW5fcGVyY19vY2MpKSAlPiUgDQogIGFycmFuZ2UoZGVzYyhhdmdfcGVyX29jY19hbGxfdGltZSkpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gaGIsIHkgPSBhdmdfcGVyX29jY19hbGxfdGltZSkpKw0KICBnZW9tX2NvbCgpKw0KICBnZW9tX3BvaW50KCkrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUpKQ0KDQpgYGANCg0KDQpgYGB7cn0NCiMgd29ya291dCB0aGUgdGVuIGxhcmdlc3QgDQp0ZW5fbGFyZ2VzdF9zcGVjaWFsaXRpZXMgPC0gYmVkcyAlPiUNCiAgZ3JvdXBfYnkoc3BlY2lhbHR5X25hbWUpICU+JSANCiAgc3VtbWFyaXNlKG1lYW5fYXZhaWxfc3RhZmZlZF9iZWRzID0gbWVhbihhdmVyYWdlX2F2YWlsYWJsZV9zdGFmZmVkX2JlZHMpKSAlPiUgDQogIGFycmFuZ2UoZGVzYyhtZWFuX2F2YWlsX3N0YWZmZWRfYmVkcykpICU+JSANCiAgc2xpY2VfbWF4KG1lYW5fYXZhaWxfc3RhZmZlZF9iZWRzLCBuPTEwKSAlPiUgDQogIHNlbGVjdCgxKSAlPiUgDQogIHB1bGwoKQ0KDQoNCg0KIyBiZWQgcGVyY2VudGFnZSBhdmFpbGFibGl0eSBmb3IgdG9wIHRlbiBsYXJnZXN0IHNwZWNpYWxpdGllcw0KYmVkcyAlPiUNCiAgZmlsdGVyKHNwZWNpYWx0eV9uYW1lICVpbiUgdGVuX2xhcmdlc3Rfc3BlY2lhbGl0aWVzKSAlPiUgDQogIGdyb3VwX2J5KHF1YXJ0ZXIsIHNwZWNpYWx0eV9uYW1lKSAlPiUNCiAgc3VtbWFyaXNlKG1lYW5fcGVyY19vY2MgPSBtZWFuKHBlcmNlbnRhZ2Vfb2NjdXBhbmN5KSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBxdWFydGVyLCB5ID0gbWVhbl9wZXJjX29jYykpKw0KICBnZW9tX2xpbmUoYWVzKGNvbG91ciA9IHNwZWNpYWx0eV9uYW1lLCBncm91cCA9IHNwZWNpYWx0eV9uYW1lKSkrDQogIGdlb21fcG9pbnQoKSsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkNCiAgDQojIGJlZCBwZXJjZW50YWdlIGF2YWlsYWJsaXR5IGZvciBhbGwgYWN1dGUNCiAgYmVkcyAlPiUNCiAgZmlsdGVyKHNwZWNpYWx0eV9uYW1lID09ICJBbGwgQWN1dGUiKSAlPiUgDQogIGdyb3VwX2J5KHF1YXJ0ZXIsIHNwZWNpYWx0eV9uYW1lKSAlPiUNCiAgc3VtbWFyaXNlKG1lYW5fcGVyY19vY2MgPSBtZWFuKHBlcmNlbnRhZ2Vfb2NjdXBhbmN5KSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBxdWFydGVyLCB5ID0gbWVhbl9wZXJjX29jYykpKw0KICBnZW9tX2xpbmUoYWVzKGNvbG91ciA9IHNwZWNpYWx0eV9uYW1lLCBncm91cCA9IHNwZWNpYWx0eV9uYW1lKSkrDQogIGdlb21fcG9pbnQoKSsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkNCiAgDQogICMgYmVkIHBlcmNlbnRhZ2UgYXZhaWxhYmlsaXR5IGZvciBpbnRlbnNpdmUgY2FyZQ0KYmVkcyAlPiUNCiAgZmlsdGVyKHNwZWNpYWx0eV9uYW1lID09ICJJbnRlbnNpdmUgQ2FyZSBNZWRpY2luZSIpICU+JSANCiAgZ3JvdXBfYnkocXVhcnRlciwgc3BlY2lhbHR5X25hbWUpICU+JQ0KICBzdW1tYXJpc2UobWVhbl9wZXJjX29jYyA9IG1lYW4ocGVyY2VudGFnZV9vY2N1cGFuY3kpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IHF1YXJ0ZXIsIHkgPSBtZWFuX3BlcmNfb2NjKSkrDQogIGdlb21fbGluZShhZXMoY29sb3VyID0gc3BlY2lhbHR5X25hbWUsIGdyb3VwID0gc3BlY2lhbHR5X25hbWUpKSsNCiAgZ2VvbV9wb2ludCgpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKQ0KICANCiAgDQogIA0KYGBgDQoNCg0KDQpgYGB7cn0NCmFfZV9iZWRzICU+JSANCiAgZ3JvdXBfYnkocXVhcnRlcikgJT4lIA0KICBzdW1tYXJpc2UobWVhbl9hdmFpbGFibGVfYmVkcyA9IG1lYW4oYXZlcmFnZV9hdmFpbGFibGVfc3RhZmZlZF9iZWRzLCBuYS5ybSA9IFRSVUUpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IHF1YXJ0ZXIsIHkgPSBtZWFuX2F2YWlsYWJsZV9iZWRzKSkrDQogIGdlb21fbGluZShncm91cCA9IjEiKSsNCiAgZ2VvbV9wb2ludCgpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1KSkNCmBgYA0KDQoNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCiMgYWdlIHNleA0KYGBge3J9DQphZ2Vfc2V4IDwtIHJlYWRfY3N2KCJyYXdfZGF0YS9ub25fY292aWRfcmF3X2RhdGEvaW5wYXRpZW50X2FuZF9kYXljYXNlX2J5X25oc19ib2FyZF9vZl90cmVhdG1lbnRfYWdlX2FuZF9zZXguY3N2IikgJT4lIGphbml0b3I6OmNsZWFuX25hbWVzKCkNCg0KaGVhbHRoX2JvYXJkX25hbWVzIDwtIHJlYWRfY3N2KCJyYXdfZGF0YS9ub25fY292aWRfcmF3X2RhdGEvaGVhbHRoX2JvYXJkX25hbWVzLmNzdiIpDQoNCmFnZV9zZXggJT4lIA0KICBjb3VudChoYikNCg0Kc2Vhc29uX2FnZV9zZXggPC0gYWdlX3NleCAlPiUgDQogIG11dGF0ZShkYXRlID0geXEocXVhcnRlciksDQogICAgICAgICB5ZWFyID0geWVhcihkYXRlKSwNCiAgICAgICAgIG1vbnRoID0gbW9udGgoZGF0ZSwgbGFiZWwgPSBUUlVFLCBhYmJyID0gRkFMU0UpLA0KICAgICAgICAgc2Vhc29uID0gY2FzZV93aGVuKA0KICAgICAgICAgICBzdHJfZGV0ZWN0KG1vbnRoLCAiRGVjZW1iZXIiKSB+ICJXaW50ZXIiLA0KICAgICAgICAgICBzdHJfZGV0ZWN0KG1vbnRoLCAiSmFudWFyeSIpIH4gIldpbnRlciIsDQogICAgICAgICAgIHN0cl9kZXRlY3QobW9udGgsICJGZWJydWFyeSIpIH4gIldpbnRlciIsDQogICAgICAgICAgIHN0cl9kZXRlY3QobW9udGgsICJNYXJjaCIpIH4gIlNwcmluZyIsDQogICAgICAgICAgIHN0cl9kZXRlY3QobW9udGgsICJBcHJpbCIpIH4gIlNwcmluZyIsDQogICAgICAgICAgIHN0cl9kZXRlY3QobW9udGgsICJNYXkiKSB+ICJTcHJpbmciLA0KICAgICAgICAgICBzdHJfZGV0ZWN0KG1vbnRoLCAiSnVuZSIpIH4gIlN1bW1lciIsDQogICAgICAgICAgIHN0cl9kZXRlY3QobW9udGgsICJKdWx5IikgfiAiU3VtbWVyIiwNCiAgICAgICAgICAgc3RyX2RldGVjdChtb250aCwgIkF1Z3VzdCIpIH4gIlN1bW1lciIsDQogICAgICAgICAgIHN0cl9kZXRlY3QobW9udGgsICJTZXB0ZW1iZXIiKSB+ICJBdXR1bW4iLA0KICAgICAgICAgICBzdHJfZGV0ZWN0KG1vbnRoLCAiT2N0b2JlciIpIH4gIkF1dHVtbiIsDQogICAgICAgICAgIHN0cl9kZXRlY3QobW9udGgsICJOb3ZlbWJlciIpIH4gIkF1dHVtbiIpLA0KICAgICAgICAgc2Vhc29uID0gZmFjdG9yKHNlYXNvbiwgb3JkZXIgPSBUUlVFKSkgDQpgYGANCmBgYHtyfQ0KDQpsaWJyYXJ5KGx1YnJpZGF0ZSkNCmxpYnJhcnkoem9vKQ0KDQojIGNoYW5nZSBxdWFydGVyIGNvbHVtbiBpbnRvIHRoZSBkYXRlIGF0IHRoZSBzdGFydCBvZiBlYWNoIHF1YXJ0ZXINCiBhZ2Vfc2V4IDwtICBhZ2Vfc2V4ICU+JSANCiAgICBtdXRhdGUocXVhcnRlciA9IHlxKHF1YXJ0ZXIpKQ0KDQogIyBzaG93cyB0aGUgdG90YWwgbGVuZ3RoIG9mIHN0YXkgYnkgYWdlIGJyYWNrZXQgZm9yIGVtZXJnZW5jeSBpbnBhdGllbnRzDQphZ2Vfc2V4ICU+JSANCiAgZmlsdGVyKGFkbWlzc2lvbl90eXBlID09ICJFbWVyZ2VuY3kgSW5wYXRpZW50cyIpICU+JSANCiAgZ3JvdXBfYnkocXVhcnRlciwgYWdlKSAlPiUgDQogIHN1bW1hcmlzZSh0b3RhbF9sZW5ndGhfb2Zfc3RheSA9IHN1bShsZW5ndGhfb2Zfc3RheSkpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gcXVhcnRlciwgeSA9IHRvdGFsX2xlbmd0aF9vZl9zdGF5KSkrDQogIGdlb21fbGluZShhZXMoY29sb3VyID0gYWdlKSkrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUpKQ0KDQoNCmBgYA0KDQoNCg0KDQoNCmBgYHtyfQ0KYWdlX3NleCAlPiUgDQpjb3VudChhZG1pc3Npb25fdHlwZSkNCg0KYWdlX3NleA0KYGBgDQoNCmBgYHtyfQ0KICMgc2hvd3MgdGhlIHRvdGFsIGxlbmd0aCBvZiBzdGF5IGJ5IGFnZSBicmFja2V0IGZvciBlbGVjdGl2ZSBpbnBhdGllbnRzDQphZ2Vfc2V4ICU+JSANCiAgZmlsdGVyKGFkbWlzc2lvbl90eXBlID09ICJFbGVjdGl2ZSBJbnBhdGllbnRzIikgJT4lIA0KICBncm91cF9ieShxdWFydGVyLCBhZ2UpICU+JSANCiAgc3VtbWFyaXNlKHRvdGFsX2xlbmd0aF9vZl9zdGF5ID0gc3VtKGxlbmd0aF9vZl9zdGF5KSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBxdWFydGVyLCB5ID0gdG90YWxfbGVuZ3RoX29mX3N0YXkpKSsNCiAgZ2VvbV9saW5lKGFlcyhjb2xvdXIgPSBhZ2UpKSsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSkpDQpgYGANCg0KYGBge3J9DQogIyBzaG93cyB0aGUgbWVhbiBsZW5ndGggb2Ygc3RheSBieSBhZ2UgYnJhY2tldCBmb3IgZW1lcmdlbmN5IGlucGF0aWVudHMNCiNjYW4gZmFjZXQgYnkgc2V4IGFsc28gaWYgcmVxdWlyZWQNCmFnZV9zZXggJT4lIA0KICBmaWx0ZXIoYWRtaXNzaW9uX3R5cGUgPT0gIkVtZXJnZW5jeSBJbnBhdGllbnRzIikgJT4lIA0KICBncm91cF9ieShxdWFydGVyLCBhZ2UpICU+JSANCiAgc3VtbWFyaXNlKGF2Z19sZW5ndGhfb2Zfc3RheSA9IG1lYW4oYXZlcmFnZV9sZW5ndGhfb2Zfc3RheSwgbmEucm0gPSBUUlVFKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBxdWFydGVyLCB5ID0gYXZnX2xlbmd0aF9vZl9zdGF5KSkrDQogIGdlb21fbGluZShhZXMoY29sb3VyID0gYWdlLCBncm91cCA9IGFnZSkpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1KSkNCiAgI2ZhY2V0X3dyYXAoIH4gc2V4KQ0KDQogIyBzaG93cyB0aGUgbWVhbiBsZW5ndGggb2Ygc3RheSBieSBhZ2UgYnJhY2tldCBmb3IgZWxlY3RpdmUgaW5wYXRpZW50cw0KIyBjYW4gZmFjZXQgYnkgc2V4IA0KYWdlX3NleCAlPiUgDQogIGZpbHRlcihhZG1pc3Npb25fdHlwZSA9PSAiRWxlY3RpdmUgSW5wYXRpZW50cyIpICU+JSANCiAgZ3JvdXBfYnkocXVhcnRlciwgYWdlKSAlPiUgDQogIHN1bW1hcmlzZShhdmdfbGVuZ3RoX29mX3N0YXkgPSBtZWFuKGF2ZXJhZ2VfbGVuZ3RoX29mX3N0YXksIG5hLnJtID0gVFJVRSkpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gcXVhcnRlciwgeSA9IGF2Z19sZW5ndGhfb2Zfc3RheSkpKw0KICBnZW9tX2xpbmUoYWVzKGNvbG91ciA9IGFnZSwgZ3JvdXAgPSBhZ2UpKSsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSkpDQojICAgI2ZhY2V0X3dyYXAofiBzZXgpDQpgYGANCg0KYGBge3J9DQphZ2Vfc2V4ICU+JSANCiAgbXV0YXRlKGRhdGUgPSB5cShxdWFydGVyKSwNCiAgICAgICAgIHllYXIgPSB5ZWFyKGRhdGUpLA0KICAgICAgICAgbW9udGggPSBtb250aChkYXRlLCBsYWJlbCA9IFRSVUUsIGFiYnIgPSBGQUxTRSksDQogICAgICAgICBzZWFzb24gPSBjYXNlX3doZW4oDQogICAgICAgICAgIHN0cl9kZXRlY3QobW9udGgsICJEZWNlbWJlciIpIH4gIldpbnRlciIsDQogICAgICAgICAgIHN0cl9kZXRlY3QobW9udGgsICJKYW51YXJ5IikgfiAiV2ludGVyIiwNCiAgICAgICAgICAgc3RyX2RldGVjdChtb250aCwgIkZlYnJ1YXJ5IikgfiAiV2ludGVyIiwNCiAgICAgICAgICAgc3RyX2RldGVjdChtb250aCwgIk1hcmNoIikgfiAiU3ByaW5nIiwNCiAgICAgICAgICAgc3RyX2RldGVjdChtb250aCwgIkFwcmlsIikgfiAiU3ByaW5nIiwNCiAgICAgICAgICAgc3RyX2RldGVjdChtb250aCwgIk1heSIpIH4gIlNwcmluZyIsDQogICAgICAgICAgIHN0cl9kZXRlY3QobW9udGgsICJKdW5lIikgfiAiU3VtbWVyIiwNCiAgICAgICAgICAgc3RyX2RldGVjdChtb250aCwgIkp1bHkiKSB+ICJTdW1tZXIiLA0KICAgICAgICAgICBzdHJfZGV0ZWN0KG1vbnRoLCAiQXVndXN0IikgfiAiU3VtbWVyIiwNCiAgICAgICAgICAgc3RyX2RldGVjdChtb250aCwgIlNlcHRlbWJlciIpIH4gIkF1dHVtbiIsDQogICAgICAgICAgIHN0cl9kZXRlY3QobW9udGgsICJPY3RvYmVyIikgfiAiQXV0dW1uIiwNCiAgICAgICAgICAgc3RyX2RldGVjdChtb250aCwgIk5vdmVtYmVyIikgfiAiQXV0dW1uIiksDQogICAgICAgICBzZWFzb24gPSBmYWN0b3Ioc2Vhc29uLCBvcmRlciA9IFRSVUUpKSANCmBgYA0KDQoNCmBgYHtyfQ0KDQphZ2Vfc2V4ICU+JSANCiAgZmlsdGVyKGFkbWlzc2lvbl90eXBlID09ICJFbWVyZ2VuY3kgSW5wYXRpZW50cyIpICU+JSANCiAgZ3JvdXBfYnkocXVhcnRlciwgc2V4KSAlPiUgDQogIHN1bW1hcmlzZShhdmdfbGVuZ3RoX29mX3N0YXkgPSBtZWFuKGF2ZXJhZ2VfbGVuZ3RoX29mX3N0YXksIG5hLnJtID0gVFJVRSkpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gcXVhcnRlciwgeSA9IGF2Z19sZW5ndGhfb2Zfc3RheSkpKw0KICBnZW9tX2xpbmUoYWVzKGNvbG91ciA9IHNleCwgZ3JvdXAgPSBzZXgpKSsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSkpKw0KICBnZW9tX3Ntb290aChhZXMoY29sb3VyID0gc2V4LCBncm91cCA9IHNleCksIHNlID0gRkFMU0UpKw0KICBnZW9tX3BvaW50KGFlcyhjb2xvdXIgPSBzZXgpLCBzaXplID0gMC41KSsNCiAgbGFicyh0aXRsZSA9ICJFbWVyZ2VuY3kgSW5wYXRpZW50IGJ5IGdlbmRlciBhbmQgYXZlcmFnZSBsZW5ndGggb2Ygc3RheSIpDQoNCg0KYWdlX3NleCAlPiUgDQogIGZpbHRlcihhZG1pc3Npb25fdHlwZSA9PSAiRWxlY3RpdmUgSW5wYXRpZW50cyIpICU+JSANCiAgZ3JvdXBfYnkocXVhcnRlciwgc2V4KSAlPiUgDQogIHN1bW1hcmlzZShhdmdfbGVuZ3RoX29mX3N0YXkgPSBtZWFuKGF2ZXJhZ2VfbGVuZ3RoX29mX3N0YXksIG5hLnJtID0gVFJVRSkpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gcXVhcnRlciwgeSA9IGF2Z19sZW5ndGhfb2Zfc3RheSkpKw0KICBnZW9tX2xpbmUoYWVzKGNvbG91ciA9IHNleCwgZ3JvdXAgPSBzZXgpKSsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSkpKw0KICBnZW9tX3Ntb290aChhZXMoY29sb3VyID0gc2V4LCBncm91cCA9IHNleCksIHNlID0gRkFMU0UpKw0KICBnZW9tX3BvaW50KGFlcyhjb2xvdXIgPSBzZXgpLCBzaXplID0gMC41KSsNCiAgbGFicyh0aXRsZSA9ICJFbGVjdGl2ZSBJbnBhdGllbnQgYnkgZ2VuZGVyIGFuZCBhdmVyYWdlIGxlbmd0aCBvZiBzdGF5IikNCg0KYGBgDQoNCg0KYGBge3J9DQojIGVtZXJnZW5jeSBpbnBhdGllbnQgYnkgYWdlIGFuZCBhdmcgbGVuZ3RoIG9mIHN0YXkNCmFnZV9zZXggJT4lIA0KICBmaWx0ZXIoYWRtaXNzaW9uX3R5cGUgPT0gIkVtZXJnZW5jeSBJbnBhdGllbnRzIikgJT4lIA0KICBncm91cF9ieShxdWFydGVyLCBhZ2UpICU+JSANCiAgc3VtbWFyaXNlKGF2Z19sZW5ndGhfb2Zfc3RheSA9IG1lYW4oYXZlcmFnZV9sZW5ndGhfb2Zfc3RheSwgbmEucm0gPSBUUlVFKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBxdWFydGVyLCB5ID0gYXZnX2xlbmd0aF9vZl9zdGF5KSkrDQogIGdlb21fbGluZShhZXMoY29sb3VyID0gYWdlLCBncm91cCA9IGFnZSkpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1KSkrDQogICNnZW9tX3Ntb290aChhZXMoY29sb3VyID0gc2V4LCBncm91cCA9IHNleCksIHNlID0gRkFMU0UpKw0KICBnZW9tX3BvaW50KGFlcyhjb2xvdXIgPSBhZ2UpLCBzaXplID0gMC41KSsNCiAgbGFicyh0aXRsZSA9ICJFbWVyZ2VuY3kgaW5wYXRpZW50IGJ5IGFnZSBhbmQgYXZnIGxlbmd0aCBvZiBzdGF5IikNCg0KIyBlbGVjdGl2ZSBpbnBhdGllbnQgYnkgYWdlIGFuZCBhdmcgbGVuZ3RoIG9mIHN0YXkNCmFnZV9zZXggJT4lIA0KICBmaWx0ZXIoYWRtaXNzaW9uX3R5cGUgPT0gIkVsZWN0aXZlIElucGF0aWVudHMiKSAlPiUgDQogIGdyb3VwX2J5KHF1YXJ0ZXIsIGFnZSkgJT4lIA0KICBzdW1tYXJpc2UoYXZnX2xlbmd0aF9vZl9zdGF5ID0gbWVhbihhdmVyYWdlX2xlbmd0aF9vZl9zdGF5LCBuYS5ybSA9IFRSVUUpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IHF1YXJ0ZXIsIHkgPSBhdmdfbGVuZ3RoX29mX3N0YXkpKSsNCiAgZ2VvbV9saW5lKGFlcyhjb2xvdXIgPSBhZ2UsIGdyb3VwID0gYWdlKSkrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUpKSsNCiAgI2dlb21fc21vb3RoKGFlcyhjb2xvdXIgPSBzZXgsIGdyb3VwID0gc2V4KSwgc2UgPSBGQUxTRSkrDQogIGdlb21fcG9pbnQoYWVzKGNvbG91ciA9IGFnZSksIHNpemUgPSAwLjUpKw0KICBsYWJzKHRpdGxlID0gIkVsZWN0aXZlIGlucGF0aWVudCBieSBhZ2UgYW5kIGF2ZyBsZW5ndGggb2Ygc3RheSIpDQpgYGANCg0KYGBge3J9DQojIGVtZXJnZW5jeSBpbnBhdGllbnQgYnkgYWdlIGFuZCBhdmcgbGVuZ3RoIG9mIGVwc2lvZGUNCmFnZV9zZXggJT4lIA0KICBmaWx0ZXIoYWRtaXNzaW9uX3R5cGUgPT0gIkVtZXJnZW5jeSBJbnBhdGllbnRzIikgJT4lIA0KICBncm91cF9ieShxdWFydGVyLCBhZ2UpICU+JSANCiAgc3VtbWFyaXNlKGF2Z19sZW5ndGhfb2ZfZXBpc29kZSA9IG1lYW4oYXZlcmFnZV9sZW5ndGhfb2ZfZXBpc29kZSwgbmEuYXJtID0gVFJVRSkpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gcXVhcnRlciwgeSA9IGF2Z19sZW5ndGhfb2ZfZXBpc29kZSkpKw0KICBnZW9tX2xpbmUoYWVzKGNvbG91ciA9IGFnZSwgZ3JvdXAgPSBhZ2UpKSsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSkpKw0KICAjZ2VvbV9zbW9vdGgoYWVzKGNvbG91ciA9IHNleCwgZ3JvdXAgPSBzZXgpLCBzZSA9IEZBTFNFKSsNCiAgZ2VvbV9wb2ludChhZXMoY29sb3VyID0gYWdlKSwgc2l6ZSA9IDAuNSkrDQogIGxhYnModGl0bGUgPSAiRW1lcmdlbmN5IGlucGF0aWVudCBieSBhZ2UgYW5kIGF2ZyBsZW5ndGggb2YgZXBpc29kZSIpDQoNCiMgZWxlY3RpdmUgaW5wYXRpZW50IGJ5IGFnZSBhbmQgYXZnIGxlbmd0aCBvZiBlcGlzb2RlDQphZ2Vfc2V4ICU+JSANCiAgZmlsdGVyKGFkbWlzc2lvbl90eXBlID09ICJFbGVjdGl2ZSBJbnBhdGllbnRzIikgJT4lIA0KICBncm91cF9ieShxdWFydGVyLCBhZ2UpICU+JSANCiAgc3VtbWFyaXNlKGF2Z19sZW5ndGhfb2ZfZXBpc29kZSA9IG1lYW4oYXZlcmFnZV9sZW5ndGhfb2ZfZXBpc29kZSwgbmEucm0gPSBUUlVFKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBxdWFydGVyLCB5ID0gYXZnX2xlbmd0aF9vZl9lcGlzb2RlKSkrDQogIGdlb21fbGluZShhZXMoY29sb3VyID0gYWdlLCBncm91cCA9IGFnZSkpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1KSkrDQogICNnZW9tX3Ntb290aChhZXMoY29sb3VyID0gc2V4LCBncm91cCA9IHNleCksIHNlID0gRkFMU0UpKw0KICBnZW9tX3BvaW50KGFlcyhjb2xvdXIgPSBhZ2UpLCBzaXplID0gMC41KSsNCiAgbGFicyh0aXRsZSA9ICJFbGVjdGl2ZSBpbnBhdGllbnQgYnkgYWdlIGFuZCBhdmcgbGVuZ3RoIG9mIGVwaXNvZGUiKQ0KYGBgDQoNCmBgYHtyfQ0KIyBlbWVyZ2VuY3kgaW5wYXRpZW50IGJ5IGFnZSBhbmQgYXZnIGVwaXNvZGVzDQphZ2Vfc2V4ICU+JSANCiAgZmlsdGVyKGFkbWlzc2lvbl90eXBlID09ICJFbWVyZ2VuY3kgSW5wYXRpZW50cyIpICU+JSANCiAgZ3JvdXBfYnkocXVhcnRlciwgYWdlKSAlPiUgDQogIHN1bW1hcmlzZShhdmdfZXBpc29kZXMgPSBtZWFuKGVwaXNvZGVzLCBuYS5ybSA9IFRSVUUpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IHF1YXJ0ZXIsIHkgPSBhdmdfZXBpc29kZXMpKSsNCiAgZ2VvbV9saW5lKGFlcyhjb2xvdXIgPSBhZ2UsIGdyb3VwID0gYWdlKSkrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUpKSsNCiAgI2dlb21fc21vb3RoKGFlcyhjb2xvdXIgPSBzZXgsIGdyb3VwID0gc2V4KSwgc2UgPSBGQUxTRSkrDQogIGdlb21fcG9pbnQoYWVzKGNvbG91ciA9IGFnZSksIHNpemUgPSAwLjUpKw0KICBsYWJzKHRpdGxlID0gIkVtZXJnZW5jeSBpbnBhdGllbnQgYnkgYWdlIGFuZCBhdmcgZXBpc29kZXMiKQ0KDQojIGVtZXJnZW5jeSBpbnBhdGllbnQgYnkgYWdlIGFuZCBhdmcgZXBpc29kZXMNCmFnZV9zZXggJT4lIA0KICBmaWx0ZXIoYWRtaXNzaW9uX3R5cGUgPT0gIkVsZWN0aXZlIElucGF0aWVudHMiKSAlPiUgDQogIGdyb3VwX2J5KHF1YXJ0ZXIsIGFnZSkgJT4lIA0KICBzdW1tYXJpc2UoYXZnX2VwaXNvZGVzID0gbWVhbihlcGlzb2RlcywgbmEucm0gPSBUUlVFKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBxdWFydGVyLCB5ID0gYXZnX2VwaXNvZGVzKSkrDQogIGdlb21fbGluZShhZXMoY29sb3VyID0gYWdlLCBncm91cCA9IGFnZSkpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1KSkrDQogICNnZW9tX3Ntb290aChhZXMoY29sb3VyID0gc2V4LCBncm91cCA9IHNleCksIHNlID0gRkFMU0UpKw0KICBnZW9tX3BvaW50KGFlcyhjb2xvdXIgPSBhZ2UpLCBzaXplID0gMC41KSsNCiAgbGFicyh0aXRsZSA9ICJFbGVjdGl2ZSBpbnBhdGllbnQgYnkgYWdlIGFuZCBhdmcgZXBpc29kZXMiKQ0KYGBgDQoNCg0KDQpgYGB7cn0NCiMgUGxvdCBjb21wYXJpc29uIG9mIEVtZXJnZW5jeSB2cyBFbGVjdGl2ZSBzdWJtaXNzaW9ucw0KYWdlX3NleCAlPiUgDQogIGZpbHRlcihhZG1pc3Npb25fdHlwZSAlaW4lIGMoIkVtZXJnZW5jeSBJbnBhdGllbnRzIiwgIkVsZWN0aXZlIElucGF0aWVudHMiKSkgJT4lIA0KICBncm91cF9ieShxdWFydGVyLCBhZG1pc3Npb25fdHlwZSkgJT4lIA0KICBzdW1tYXJpc2UoYXZnX3N0YXkgPSBtZWFuKGF2ZXJhZ2VfbGVuZ3RoX29mX3N0YXksIG5hLnJtID0gVFJVRSkpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gcXVhcnRlciwgeSA9IGF2Z19zdGF5LCBjb2xvdXIgPSBhZG1pc3Npb25fdHlwZSkpKw0KICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gYWRtaXNzaW9uX3R5cGUpKSsNCiAgZ2VvbV9wb2ludCgpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKQ0KDQpgYGANCg0KDQpgYGB7cn0NCiMgYXZnX3N0YXkgYnkgYWRtaXNzaW9uIHR5cGUNCmFnZV9zZXggJT4lIA0KICBncm91cF9ieShxdWFydGVyLCBhZG1pc3Npb25fdHlwZSkgJT4lIA0KICBzdW1tYXJpc2UoYXZnX3N0YXkgPSBtZWFuKGF2ZXJhZ2VfbGVuZ3RoX29mX3N0YXksIG5hLnJtID0gVFJVRSkpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gcXVhcnRlciwgeSA9IGF2Z19zdGF5LCBjb2xvdXIgPSBhZG1pc3Npb25fdHlwZSkpKw0KICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gYWRtaXNzaW9uX3R5cGUpKSsNCiAgZ2VvbV9wb2ludCgpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKQ0KDQoNCiMgYXZnX3N0YXkgZm9yIGFsbCB0eXBlcw0KYWdlX3NleCAlPiUgDQogIGdyb3VwX2J5KHF1YXJ0ZXIpICU+JSANCiAgc3VtbWFyaXNlKGF2Z19zdGF5ID0gbWVhbihhdmVyYWdlX2xlbmd0aF9vZl9zdGF5LCBuYS5ybSA9IFRSVUUpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IHF1YXJ0ZXIsIHkgPSBhdmdfc3RheSwgZ3JvdXAgPSAxKSkrDQogIGdlb21fbGluZShhZXMoZ3JvdXAgPSAxKSkrDQogIGdlb21fcG9pbnQoKSsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkNCg0KIyBudW1iZXIgb2Ygc3RheXMgZm9yIGFsbCB0eXBlcw0KYWdlX3NleCAlPiUgDQogIGdyb3VwX2J5KHF1YXJ0ZXIpICU+JSANCiAgc3VtbWFyaXNlKHRvdGFsX3N0YXlzID0gc3VtKHN0YXlzLCBuYS5ybSA9IFRSVUUpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IHF1YXJ0ZXIsIHkgPSB0b3RhbF9zdGF5cywgZ3JvdXAgPSAxKSkrDQogIGdlb21fbGluZShhZXMoZ3JvdXAgPSAxKSkrDQogIGdlb21fcG9pbnQoKSsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkNCmBgYA0KDQoNCg0KDQoNCg0KDQoNCg0KIyBTSU1EDQoNCmBgYHtyfQ0Kc2ltZCA8LSByZWFkX2NzdigicmF3X2RhdGEvbm9uX2NvdmlkX3Jhd19kYXRhL2lucGF0aWVudF9hbmRfZGF5Y2FzZV9ieV9uaHNfYm9hcmRfb2ZfdHJlYXRtZW50X2FuZF9zaW1kLmNzdiIpICU+JSBqYW5pdG9yOjpjbGVhbl9uYW1lcygpDQpgYGANCmBgYHtyfQ0KI3RvdGFsIGVwaXNvZGVzKGhvc3BpdGFsaXNhdGlvbnM/KSBieSBzaW1kIHZhbHVlDQpzaW1kICU+JSANCiAgZHJvcF9uYShzaW1kKSAlPiUNCiAgbXV0YXRlKHNpbWQgPSBhcy5mYWN0b3Ioc2ltZCkpICU+JSAjIGdpdmVzIGVhY2ggc2ltZCBhIHNlcGFyYXRlIGNvbG91cg0KICBncm91cF9ieShxdWFydGVyLCBzaW1kKSAlPiUgDQogIHN1bW1hcmlzZSh0b3RhbF9lcGlzb2RlcyA9IHN1bShlcGlzb2RlcywgbmEucm0gPSBUUlVFKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBxdWFydGVyLCB5ID0gdG90YWxfZXBpc29kZXMsIGdyb3VwID0gc2ltZCkpKw0KICBnZW9tX2xpbmUoYWVzKGNvbG91ciA9IHNpbWQpKSsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkrDQogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OmNvbW1hKQ0KICANCiNhdmcgbnVtYmVyIG9mIGVwaXNvZGVzKGhvc3BpdGFsaXNhdGlvbnM/KSBieSBzaW1kIHZhbHVlDQpzaW1kICU+JSANCiAgZHJvcF9uYShzaW1kKSAlPiUNCiAgbXV0YXRlKHNpbWQgPSBhcy5mYWN0b3Ioc2ltZCkpICU+JSAjIGdpdmVzIGVhY2ggc2ltZCBhIHNlcGFyYXRlIGNvbG91cg0KICBncm91cF9ieShxdWFydGVyLCBzaW1kKSAlPiUgDQogIHN1bW1hcmlzZShhdmdfZXBpc29kZXMgPSBtZWFuKGVwaXNvZGVzLCBuYS5ybSA9IFRSVUUpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IHF1YXJ0ZXIsIHkgPSBhdmdfZXBpc29kZXMsIGdyb3VwID0gc2ltZCkpKw0KICBnZW9tX2xpbmUoYWVzKGNvbG91ciA9IHNpbWQpKSsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkrDQogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OmNvbW1hKQ0KDQojYXZnIHN0YXlzIGJ5IHNpbWQgdmFsdWUNCnNpbWQgJT4lIA0KICBkcm9wX25hKHNpbWQpICU+JQ0KICBtdXRhdGUoc2ltZCA9IGFzLmZhY3RvcihzaW1kKSkgJT4lICMgZ2l2ZXMgZWFjaCBzaW1kIGEgc2VwYXJhdGUgY29sb3VyDQogIGdyb3VwX2J5KHF1YXJ0ZXIsIHNpbWQpICU+JSANCiAgc3VtbWFyaXNlKGF2Z19zdGF5cyA9IG1lYW4oc3RheXMsIG5hLnJtID0gVFJVRSkpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gcXVhcnRlciwgeSA9IGF2Z19zdGF5cywgZ3JvdXAgPSBzaW1kKSkrDQogIGdlb21fbGluZShhZXMoY29sb3VyID0gc2ltZCkpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKSsNCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6Y29tbWEpDQogIA0KYGBgDQpgYGB7cn0NCiN0b3RhbCBlcGlzb2Rlcyhob3NwaXRhbGlzYXRpb25zPykgYnkgc2ltZCB2YWx1ZQ0Kc2ltZCAlPiUgDQogIGRyb3BfbmEoc2ltZCkgJT4lDQogIGZpbHRlcihhZG1pc3Npb25fdHlwZSA9PSAiRW1lcmdlbmN5IElucGF0aWVudHMiKSAlPiUgDQogIG11dGF0ZShzaW1kID0gYXMuZmFjdG9yKHNpbWQpKSAlPiUgIyBnaXZlcyBlYWNoIHNpbWQgYSBzZXBhcmF0ZSBjb2xvdXINCiAgZ3JvdXBfYnkocXVhcnRlciwgc2ltZCkgJT4lIA0KICBzdW1tYXJpc2UodG90YWxfZXBpc29kZXMgPSBzdW0oZXBpc29kZXMsIG5hLnJtID0gVFJVRSkpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gcXVhcnRlciwgeSA9IHRvdGFsX2VwaXNvZGVzLCBncm91cCA9IHNpbWQpKSsNCiAgZ2VvbV9saW5lKGFlcyhjb2xvdXIgPSBzaW1kKSkrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpjb21tYSkNCiAgDQojYXZnIG51bWJlciBvZiBlcGlzb2Rlcyhob3NwaXRhbGlzYXRpb25zPykgYnkgc2ltZCB2YWx1ZQ0Kc2ltZCAlPiUgDQogIGRyb3BfbmEoc2ltZCkgJT4lDQogIGZpbHRlcihhZG1pc3Npb25fdHlwZSA9PSAiRW1lcmdlbmN5IElucGF0aWVudHMiKSAlPiUgDQogIG11dGF0ZShzaW1kID0gYXMuZmFjdG9yKHNpbWQpKSAlPiUgIyBnaXZlcyBlYWNoIHNpbWQgYSBzZXBhcmF0ZSBjb2xvdXINCiAgZ3JvdXBfYnkocXVhcnRlciwgc2ltZCkgJT4lIA0KICBzdW1tYXJpc2UoYXZnX2VwaXNvZGVzID0gbWVhbihlcGlzb2RlcywgbmEucm0gPSBUUlVFKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBxdWFydGVyLCB5ID0gYXZnX2VwaXNvZGVzLCBncm91cCA9IHNpbWQpKSsNCiAgZ2VvbV9saW5lKGFlcyhjb2xvdXIgPSBzaW1kKSkrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpjb21tYSkNCg0KI2F2ZyBzdGF5cyBieSBzaW1kIHZhbHVlDQpzaW1kICU+JSANCiAgZHJvcF9uYShzaW1kKSAlPiUNCiAgZmlsdGVyKGFkbWlzc2lvbl90eXBlID09ICJFbWVyZ2VuY3kgSW5wYXRpZW50cyIpICU+JSANCiAgbXV0YXRlKHNpbWQgPSBhcy5mYWN0b3Ioc2ltZCkpICU+JSAjIGdpdmVzIGVhY2ggc2ltZCBhIHNlcGFyYXRlIGNvbG91cg0KICBncm91cF9ieShxdWFydGVyLCBzaW1kKSAlPiUgDQogIHN1bW1hcmlzZShhdmdfc3RheXMgPSBtZWFuKHN0YXlzLCBuYS5ybSA9IFRSVUUpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IHF1YXJ0ZXIsIHkgPSBhdmdfc3RheXMsIGdyb3VwID0gc2ltZCkpKw0KICBnZW9tX2xpbmUoYWVzKGNvbG91ciA9IHNpbWQpKSsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkrDQogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OmNvbW1hKQ0KICANCg0KYGBgDQoNCg0KYGBge3J9DQojIHBsb3QgYXZnIHN0YXkgbGVuZ3RoIGZvciBtb3N0IGFuZCBsZWFzdCBkZXByaXZlZCBmb3IgZW1lcmdlbmN5IHVucGF0aWVudHMNCnNpbWQgJT4lIA0KICBmaWx0ZXIoYWRtaXNzaW9uX3R5cGUgPT0gIkVtZXJnZW5jeSBJbnBhdGllbnRzIiwgc2ltZCAlaW4lIGMoMSw1KSkgJT4lIA0KICBkcm9wX25hKHNpbWQpICU+JSANCiAgZ3JvdXBfYnkocXVhcnRlcixzaW1kKSAlPiUgDQogIHN1bW1hcmlzZShhdmdfc3RheV9sZW5ndGggPSBtZWFuKGF2ZXJhZ2VfbGVuZ3RoX29mX3N0YXksIG5hLnJtID0gVFJVRSkpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gcXVhcnRlciwgeSA9IGF2Z19zdGF5X2xlbmd0aCkpICsNCiAgZ2VvbV9saW5lKGFlcyhjb2xvdXIgPSBzaW1kLCBncm91cCA9IHNpbWQpKSsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkNCiAgDQpgYGANCg0KDQpgYGB7cn0NCnNwZWNpYWxpdHkgPC0gcmVhZF9jc3YoInJhd19kYXRhL25vbl9jb3ZpZF9yYXdfZGF0YS9pbnBhdGllbnRfYW5kX2RheWNhc2VfYnlfbmhzX2JvYXJkX29mX3RyZWF0bWVudF9hbmRfc3BlY2lhbHR5LmNzdiIpICU+JSBqYW5pdG9yOjpjbGVhbl9uYW1lcygpDQpgYGANCg0KYGBge3J9DQpzcGVjaWFsaXR5ICU+JSANCiAgY291bnQoYWRtaXNzaW9uX3R5cGUpDQoNCnNwZWNpYWxpdHkgJT4lIA0KICBjb3VudChoYikNCg0Kc3BlY2lhbGl0eSAlPiUgDQogIGNvdW50KGxvY2F0aW9uKQ0KDQpzcGVjaWFsaXR5ICU+JSANCiAgY291bnQoc3BlY2lhbHR5X25hbWUpDQoNCiMgYWRkIGF2ZXJhZ2VzIA0Kc3BlY2lhbGl0eV9hdmVyYWdlcyA8LSBzcGVjaWFsaXR5ICU+JSANCiAgZ3JvdXBfYnkocXVhcnRlciwgYWRtaXNzaW9uX3R5cGUpICU+JSANCiAgbXV0YXRlKGF2Z19sZW5ndGhfc3BlbGw9IG1lYW4oYXZlcmFnZV9sZW5ndGhfb2Zfc3BlbGwsIG5hLnJtID0gVFJVRSksDQogICAgICAgICBhdmdfbGVuZ3RoX2VwaXNvZGUgPSBtZWFuKGF2ZXJhZ2VfbGVuZ3RoX29mX2VwaXNvZGUsIG5hLnJtID0gVFJVRSkpICU+JSANCiAgdW5ncm91cCgpDQoNCg0Kc3BlY2lhbGl0eV9hdmVyYWdlcyAlPiUgDQogIGdyb3VwX2J5KHF1YXJ0ZXIsIGFkbWlzc2lvbl90eXBlKSAlPiUgDQogIHNsaWNlKDEpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gcXVhcnRlciwgeSA9IGF2ZXJhZ2VfbGVuZ3RoX29mX2VwaXNvZGUsIGdyb3VwID0gYWRtaXNzaW9uX3R5cGUpKSArIA0KICBnZW9tX2xpbmUoYWVzKGNvbG91ciA9IGFkbWlzc2lvbl90eXBlKSkrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpDQoNCmBgYA0KDQpgYGB7cn0NCmFlX3dhaXRfdGltZXMgPC0gcmVhZF9jc3YoInJhd19kYXRhL25vbl9jb3ZpZF9yYXdfZGF0YS9tb250aGx5X2FlX3dhaXRpbmd0aW1lc18yMDIyMDYuY3N2IikgJT4lIGphbml0b3I6OmNsZWFuX25hbWVzKCkNCg0KI2dsaW1wc2UoYWVfd2FpdF90aW1lcykNCg0KDQojbWFrZSBhIGRhdGUgYW5kIHllYXIgY29sdW1uIHdpdGggdGhlIGZpcnN0IGRhdGUgb2YgZXZlcnkgbW9udGgNCmFlX3dhaXRfdGltZXMgPC0gYWVfd2FpdF90aW1lcyAlPiUgDQogIG11dGF0ZShkYXRlID0geW0obW9udGgpLCAuYWZ0ZXIgPSBtb250aCwNCiAgICAgICAgIHllYXIgPSB5ZWFyKGRhdGUpKQ0KDQojbWFrZSBhIHBlcmNlbnQgY29sdW1uIHdpdGggcGVyY2VudCBvZiBwYXRpZW50cyBtZWV0aW5nIHRoZSA0aHIgdGFyZ2V0IHRpbWUNCmFlX3dhaXRfdGltZXMgPC0gYWVfd2FpdF90aW1lcyAlPiUgDQogIG11dGF0ZShwZXJjZW50XzRocl90YXJnZXRfYWNoaWV2ZWQgPSAobnVtYmVyX21lZXRpbmdfdGFyZ2V0X2FnZ3JlZ2F0ZS9udW1iZXJfb2ZfYXR0ZW5kYW5jZXNfYWdncmVnYXRlKSoxMDApICU+JSANCiAgI2FkZCBhbiA4aHIgb25lIC0gbm90IGN1cnJlbnRseSB1c2VkDQptdXRhdGUocGVyY2VudF9zZWVuX3dpdGhpbl84aHIgPSAoKG51bWJlcl9vZl9hdHRlbmRhbmNlc19hZ2dyZWdhdGUtYXR0ZW5kYW5jZV9ncmVhdGVyOGhycykvbnVtYmVyX29mX2F0dGVuZGFuY2VzX2FnZ3JlZ2F0ZSkqMTAwKQ0KYGBgDQoNCg0KYGBge3J9DQojIGRyYXcgcGVyY2VudGFnZSBvZiA0IGhvdXIgd2FpdCBmb3IgYWxsIHllYXJzDQpmb3JfcGxvdGx5IDwtIGFlX3dhaXRfdGltZXMgJT4lIA0KICBmaWx0ZXIoZGVwYXJ0bWVudF90eXBlID09ICJFbWVyZ2VuY3kgRGVwYXJ0bWVudCIpICU+JSANCiAgZ3JvdXBfYnkoZGF0ZSwgZGVwYXJ0bWVudF90eXBlKSAlPiUgDQogIHN1bW1hcmlzZShhdmdfNGhyX3RhcmdldF9tYWRlID0gbWVhbihwZXJjZW50XzRocl90YXJnZXRfYWNoaWV2ZWQpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IGRhdGUsIHkgPSBhdmdfNGhyX3RhcmdldF9tYWRlKSkrDQogIGdlb21fbGluZShhZXMoY29sb3VyID0gZGVwYXJ0bWVudF90eXBlKSkrDQogIHNjYWxlX3hfZGF0ZShkYXRlX2JyZWFrcyA9ICI2IG1vbnRocyIsIGRhdGVfbGFiZWxzID0gICIlYiAlWSIpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCBoanVzdCA9IDEsIHNpemUgPTcpKSsNCiAgZ2VvbV9zbW9vdGgoKSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDA4LTAxLTAxIikpLCBsaW5ldHlwZT00KSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDA5LTAxLTAxIikpLCBsaW5ldHlwZT00KSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDEwLTAxLTAxIikpLCBsaW5ldHlwZT00KSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDExLTAxLTAxIikpLCBsaW5ldHlwZT00KSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDEyLTAxLTAxIikpLCBsaW5ldHlwZT00KSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDEzLTAxLTAxIikpLCBsaW5ldHlwZT00KSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDE0LTAxLTAxIikpLCBsaW5ldHlwZT00KSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDE1LTAxLTAxIikpLCBsaW5ldHlwZT00KSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDE2LTAxLTAxIikpLCBsaW5ldHlwZT00KSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDE3LTAxLTAxIikpLCBsaW5ldHlwZT00KSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDE4LTAxLTAxIikpLCBsaW5ldHlwZT00KSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDE5LTAxLTAxIikpLCBsaW5ldHlwZT00KSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDIwLTAxLTAxIikpLCBsaW5ldHlwZT00KSsNCiAgbGFicyh0aXRsZSA9ICJwZXJjZW50YWdlIG9mIEEmRSBkZXBhcnRtZW50cyBtZWV0aW5nIHRoZSA0IGhyIHRhcmdldCB0dXJuYXJvdW5kIGZvciBwYXRpZW50cyIsDQogICAgICAgc3VidGl0bGUgPSAiYWRkZWQgaW4gdmVydGljYWwgbGluZXMgZm9yIEphbnVhcnkgdG8gaGVscCIpDQoNCmdncGxvdGx5KGZvcl9wbG90bHkpDQpgYGANCg0KYGBge3J9DQojIDRociB3YWl0IGJ5IGhlYWx0aCBib2FyZCBmb3IgYWxsIHllYXJzIGZhY2V0IHdyYXBwZWQNCmFlX3dhaXRfdGltZXMgJT4lIA0KICBmaWx0ZXIoZGVwYXJ0bWVudF90eXBlID09ICJFbWVyZ2VuY3kgRGVwYXJ0bWVudCIpICU+JSANCiAgZ3JvdXBfYnkoZGF0ZSwgaGJ0KSAlPiUgDQogIG11dGF0ZShhdmdfNGhyX3RhcmdldF9tYWRlID0gbWVhbihwZXJjZW50XzRocl90YXJnZXRfYWNoaWV2ZWQpKSAlPiUgDQogIHNsaWNlKDEpICU+JSAgDQogIGdncGxvdChhZXMoeCA9IGRhdGUsIHkgPSBhdmdfNGhyX3RhcmdldF9tYWRlKSkrDQogIGdlb21fbGluZShhZXMoY29sb3VyID0gaGJ0KSkrDQogIHNjYWxlX3hfZGF0ZShkYXRlX2JyZWFrcyA9ICI2IG1vbnRocyIsIGRhdGVfbGFiZWxzID0gICIlYiAlWSIpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCBoanVzdCA9IDEsIHNpemUgPTcpKSsNCiAgZ2VvbV9zbW9vdGgoKSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDA4LTAxLTAxIikpLCBsaW5ldHlwZT00KSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDA5LTAxLTAxIikpLCBsaW5ldHlwZT00KSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDEwLTAxLTAxIikpLCBsaW5ldHlwZT00KSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDExLTAxLTAxIikpLCBsaW5ldHlwZT00KSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDEyLTAxLTAxIikpLCBsaW5ldHlwZT00KSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDEzLTAxLTAxIikpLCBsaW5ldHlwZT00KSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDE0LTAxLTAxIikpLCBsaW5ldHlwZT00KSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDE1LTAxLTAxIikpLCBsaW5ldHlwZT00KSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDE2LTAxLTAxIikpLCBsaW5ldHlwZT00KSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDE3LTAxLTAxIikpLCBsaW5ldHlwZT00KSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDE4LTAxLTAxIikpLCBsaW5ldHlwZT00KSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDE5LTAxLTAxIikpLCBsaW5ldHlwZT00KSsNCiAgZmFjZXRfd3JhcCh+IGhidCkNCmBgYA0KDQpgYGB7cn0NCnRhcmdldF8yMDA3IDwtIGFlX3dhaXRfdGltZXMgJT4lDQogIGdyb3VwX2J5KHllYXIsIGhidCkgJT4lIA0KICBzdW1tYXJpc2UoYWVfNGhyX3RhcmdldF9hY2hpZXZlZCA9IG1lYW4ocGVyY2VudF80aHJfdGFyZ2V0X2FjaGlldmVkLCBuYS5ybSA9IFRSVUUpKSAlPiUgDQogIGZpbHRlcih5ZWFyID09IDIwMDcpICU+JSANCiAgcmVuYW1lKGFlX3RhcmdldF8yMDA3ID0gYWVfNGhyX3RhcmdldF9hY2hpZXZlZCkgJT4lIA0KICB1bmdyb3VwKCkgJT4lIA0KICBzZWxlY3QoaGJ0LGFlX3RhcmdldF8yMDA3KQ0KDQp0YXJnZXRfMjAwOCA8LSBhZV93YWl0X3RpbWVzICU+JQ0KICBncm91cF9ieSh5ZWFyLCBoYnQpICU+JSANCiAgc3VtbWFyaXNlKGFlXzRocl90YXJnZXRfYWNoaWV2ZWQgPSBtZWFuKHBlcmNlbnRfNGhyX3RhcmdldF9hY2hpZXZlZCwgbmEucm0gPSBUUlVFKSkgJT4lIA0KICBmaWx0ZXIoeWVhciA9PSAyMDA4KSAlPiUgDQogIHJlbmFtZShhZV90YXJnZXRfMjAwOCA9IGFlXzRocl90YXJnZXRfYWNoaWV2ZWQpICU+JSANCiAgdW5ncm91cCgpICU+JSANCiAgc2VsZWN0KGhidCxhZV90YXJnZXRfMjAwOCkNCg0KdGFyZ2V0XzIwMDkgPC0gYWVfd2FpdF90aW1lcyAlPiUNCiAgZ3JvdXBfYnkoeWVhciwgaGJ0KSAlPiUgDQogIHN1bW1hcmlzZShhZV80aHJfdGFyZ2V0X2FjaGlldmVkID0gbWVhbihwZXJjZW50XzRocl90YXJnZXRfYWNoaWV2ZWQsIG5hLnJtID0gVFJVRSkpICU+JSANCiAgZmlsdGVyKHllYXIgPT0gMjAwOSkgJT4lIA0KICByZW5hbWUoYWVfdGFyZ2V0XzIwMDkgPSBhZV80aHJfdGFyZ2V0X2FjaGlldmVkKSAlPiUgDQogIHVuZ3JvdXAoKSAlPiUgDQogIHNlbGVjdChoYnQsYWVfdGFyZ2V0XzIwMDkpDQoNCnRhcmdldF8yMDEwIDwtIGFlX3dhaXRfdGltZXMgJT4lDQogIGdyb3VwX2J5KHllYXIsIGhidCkgJT4lIA0KICBzdW1tYXJpc2UoYWVfNGhyX3RhcmdldF9hY2hpZXZlZCA9IG1lYW4ocGVyY2VudF80aHJfdGFyZ2V0X2FjaGlldmVkLCBuYS5ybSA9IFRSVUUpKSAlPiUgDQogIGZpbHRlcih5ZWFyID09IDIwMTApICU+JSANCiAgcmVuYW1lKGFlX3RhcmdldF8yMDEwID0gYWVfNGhyX3RhcmdldF9hY2hpZXZlZCkgJT4lIA0KICB1bmdyb3VwKCkgJT4lIA0KICBzZWxlY3QoaGJ0LGFlX3RhcmdldF8yMDEwKQ0KDQp0YXJnZXRfMjAxMSA8LSBhZV93YWl0X3RpbWVzICU+JQ0KICBncm91cF9ieSh5ZWFyLCBoYnQpICU+JSANCiAgc3VtbWFyaXNlKGFlXzRocl90YXJnZXRfYWNoaWV2ZWQgPSBtZWFuKHBlcmNlbnRfNGhyX3RhcmdldF9hY2hpZXZlZCwgbmEucm0gPSBUUlVFKSkgJT4lIA0KICBmaWx0ZXIoeWVhciA9PSAyMDExKSAlPiUgDQogIHJlbmFtZShhZV90YXJnZXRfMjAxMSA9IGFlXzRocl90YXJnZXRfYWNoaWV2ZWQpICU+JSANCiAgdW5ncm91cCgpICU+JSANCiAgc2VsZWN0KGhidCxhZV90YXJnZXRfMjAxMSkNCg0KdGFyZ2V0XzIwMTIgPC0gYWVfd2FpdF90aW1lcyAlPiUNCiAgZ3JvdXBfYnkoeWVhciwgaGJ0KSAlPiUgDQogIHN1bW1hcmlzZShhZV80aHJfdGFyZ2V0X2FjaGlldmVkID0gbWVhbihwZXJjZW50XzRocl90YXJnZXRfYWNoaWV2ZWQsIG5hLnJtID0gVFJVRSkpICU+JSANCiAgZmlsdGVyKHllYXIgPT0gMjAxMikgJT4lIA0KICByZW5hbWUoYWVfdGFyZ2V0XzIwMTIgPSBhZV80aHJfdGFyZ2V0X2FjaGlldmVkKSAlPiUgDQogIHVuZ3JvdXAoKSAlPiUgDQogIHNlbGVjdChoYnQsYWVfdGFyZ2V0XzIwMTIpDQoNCnRhcmdldF8yMDEzIDwtIGFlX3dhaXRfdGltZXMgJT4lDQogIGdyb3VwX2J5KHllYXIsIGhidCkgJT4lIA0KICBzdW1tYXJpc2UoYWVfNGhyX3RhcmdldF9hY2hpZXZlZCA9IG1lYW4ocGVyY2VudF80aHJfdGFyZ2V0X2FjaGlldmVkLCBuYS5ybSA9IFRSVUUpKSAlPiUgDQogIGZpbHRlcih5ZWFyID09IDIwMTMpICU+JSANCiAgcmVuYW1lKGFlX3RhcmdldF8yMDEzID0gYWVfNGhyX3RhcmdldF9hY2hpZXZlZCkgJT4lIA0KICB1bmdyb3VwKCkgJT4lIA0KICBzZWxlY3QoaGJ0LGFlX3RhcmdldF8yMDEzKQ0KDQp0YXJnZXRfMjAxNCA8LSBhZV93YWl0X3RpbWVzICU+JQ0KICBncm91cF9ieSh5ZWFyLCBoYnQpICU+JSANCiAgc3VtbWFyaXNlKGFlXzRocl90YXJnZXRfYWNoaWV2ZWQgPSBtZWFuKHBlcmNlbnRfNGhyX3RhcmdldF9hY2hpZXZlZCwgbmEucm0gPSBUUlVFKSkgJT4lIA0KICBmaWx0ZXIoeWVhciA9PSAyMDE0KSAlPiUgDQogIHJlbmFtZShhZV90YXJnZXRfMjAxNCA9IGFlXzRocl90YXJnZXRfYWNoaWV2ZWQpICU+JSANCiAgdW5ncm91cCgpICU+JSANCiAgc2VsZWN0KGhidCxhZV90YXJnZXRfMjAxNCkNCg0KdGFyZ2V0XzIwMTUgPC0gYWVfd2FpdF90aW1lcyAlPiUNCiAgZ3JvdXBfYnkoeWVhciwgaGJ0KSAlPiUgDQogIHN1bW1hcmlzZShhZV80aHJfdGFyZ2V0X2FjaGlldmVkID0gbWVhbihwZXJjZW50XzRocl90YXJnZXRfYWNoaWV2ZWQsIG5hLnJtID0gVFJVRSkpICU+JSANCiAgZmlsdGVyKHllYXIgPT0gMjAxNSkgJT4lIA0KICByZW5hbWUoYWVfdGFyZ2V0XzIwMTUgPSBhZV80aHJfdGFyZ2V0X2FjaGlldmVkKSAlPiUgDQogIHVuZ3JvdXAoKSAlPiUgDQogIHNlbGVjdChoYnQsYWVfdGFyZ2V0XzIwMTUpDQoNCnRhcmdldF8yMDE2IDwtIGFlX3dhaXRfdGltZXMgJT4lDQogIGdyb3VwX2J5KHllYXIsIGhidCkgJT4lIA0KICBzdW1tYXJpc2UoYWVfNGhyX3RhcmdldF9hY2hpZXZlZCA9IG1lYW4ocGVyY2VudF80aHJfdGFyZ2V0X2FjaGlldmVkLCBuYS5ybSA9IFRSVUUpKSAlPiUgDQogIGZpbHRlcih5ZWFyID09IDIwMTYpICU+JSANCiAgcmVuYW1lKGFlX3RhcmdldF8yMDE2ID0gYWVfNGhyX3RhcmdldF9hY2hpZXZlZCkgJT4lIA0KICB1bmdyb3VwKCkgJT4lIA0KICBzZWxlY3QoaGJ0LGFlX3RhcmdldF8yMDE2KQ0KDQp0YXJnZXRfMjAxNyA8LSBhZV93YWl0X3RpbWVzICU+JQ0KICBncm91cF9ieSh5ZWFyLCBoYnQpICU+JSANCiAgc3VtbWFyaXNlKGFlXzRocl90YXJnZXRfYWNoaWV2ZWQgPSBtZWFuKHBlcmNlbnRfNGhyX3RhcmdldF9hY2hpZXZlZCwgbmEucm0gPSBUUlVFKSkgJT4lIA0KICBmaWx0ZXIoeWVhciA9PSAyMDE3KSAlPiUgDQogIHJlbmFtZShhZV90YXJnZXRfMjAxNyA9IGFlXzRocl90YXJnZXRfYWNoaWV2ZWQpICU+JSANCiAgdW5ncm91cCgpICU+JSANCiAgc2VsZWN0KGhidCxhZV90YXJnZXRfMjAxNykNCg0KdGFyZ2V0XzIwMTggPC0gYWVfd2FpdF90aW1lcyAlPiUNCiAgZ3JvdXBfYnkoeWVhciwgaGJ0KSAlPiUgDQogIHN1bW1hcmlzZShhZV80aHJfdGFyZ2V0X2FjaGlldmVkID0gbWVhbihwZXJjZW50XzRocl90YXJnZXRfYWNoaWV2ZWQsIG5hLnJtID0gVFJVRSkpICU+JSANCiAgZmlsdGVyKHllYXIgPT0gMjAxOCkgJT4lIA0KICByZW5hbWUoYWVfdGFyZ2V0XzIwMTggPSBhZV80aHJfdGFyZ2V0X2FjaGlldmVkKSAlPiUgDQogIHVuZ3JvdXAoKSAlPiUgDQogIHNlbGVjdChoYnQsYWVfdGFyZ2V0XzIwMTgpDQoNCnRhcmdldF8yMDE5IDwtIGFlX3dhaXRfdGltZXMgJT4lDQogIGdyb3VwX2J5KHllYXIsIGhidCkgJT4lIA0KICBzdW1tYXJpc2UoYWVfNGhyX3RhcmdldF9hY2hpZXZlZCA9IG1lYW4ocGVyY2VudF80aHJfdGFyZ2V0X2FjaGlldmVkLCBuYS5ybSA9IFRSVUUpKSAlPiUgDQogIGZpbHRlcih5ZWFyID09IDIwMTkpICU+JSANCiAgcmVuYW1lKGFlX3RhcmdldF8yMDE5ID0gYWVfNGhyX3RhcmdldF9hY2hpZXZlZCkgJT4lIA0KICB1bmdyb3VwKCkgJT4lIA0KICBzZWxlY3QoaGJ0LGFlX3RhcmdldF8yMDE5KQ0KDQp0YXJnZXRfMjAyMCA8LSBhZV93YWl0X3RpbWVzICU+JQ0KICBncm91cF9ieSh5ZWFyLCBoYnQpICU+JSANCiAgc3VtbWFyaXNlKGFlXzRocl90YXJnZXRfYWNoaWV2ZWQgPSBtZWFuKHBlcmNlbnRfNGhyX3RhcmdldF9hY2hpZXZlZCwgbmEucm0gPSBUUlVFKSkgJT4lIA0KICBmaWx0ZXIoeWVhciA9PSAyMDIwKSAlPiUgDQogIHJlbmFtZShhZV90YXJnZXRfMjAyMCA9IGFlXzRocl90YXJnZXRfYWNoaWV2ZWQpICU+JSANCiAgdW5ncm91cCgpICU+JSANCiAgc2VsZWN0KGhidCxhZV90YXJnZXRfMjAyMCkNCg0KdGFyZ2V0XzIwMjEgPC0gYWVfd2FpdF90aW1lcyAlPiUNCiAgZ3JvdXBfYnkoeWVhciwgaGJ0KSAlPiUgDQogIHN1bW1hcmlzZShhZV80aHJfdGFyZ2V0X2FjaGlldmVkID0gbWVhbihwZXJjZW50XzRocl90YXJnZXRfYWNoaWV2ZWQsIG5hLnJtID0gVFJVRSkpICU+JSANCiAgZmlsdGVyKHllYXIgPT0gMjAyMSkgJT4lIA0KICByZW5hbWUoYWVfdGFyZ2V0XzIwMjEgPSBhZV80aHJfdGFyZ2V0X2FjaGlldmVkKSAlPiUgDQogIHVuZ3JvdXAoKSAlPiUgDQogIHNlbGVjdChoYnQsYWVfdGFyZ2V0XzIwMjEpDQoNCmBgYA0KDQoNCg0KDQoNCg0KYGBge3J9DQpsaWJyYXJ5KHNmKQ0KDQpzY290bGFuZCA8LSBzdF9yZWFkKCIuLi9TR19OSFNfSGVhbHRoQm9hcmRzXzIwMTlfc2hhcGVmaWxlL1NHX05IU19IZWFsdGhCb2FyZHNfMjAxOS5zaHAiKQ0KDQojIHZpZXcoc2NvdGxhbmQpDQojIA0KaGVhZChzY290bGFuZCwgMykNCiMgDQpwbG90KHNjb3RsYW5kWy0xXSkNCg0Kc2NvdGxhbmQgPC0gIHNjb3RsYW5kICU+JSANCiAgbXV0YXRlKGNlbnRyZXMgPSBzdF9jZW50cm9pZChzdF9tYWtlX3ZhbGlkKGdlb21ldHJ5KSkpICU+JQ0KICAgIG11dGF0ZShsYXQgPSBzdF9jb29yZGluYXRlcyhjZW50cmVzKVssMV0sDQogICAgICAgICAgIGxvbmcgPSBzdF9jb29yZGluYXRlcyhjZW50cmVzKVssMl0sDQogICAgICAgICAgIHRhcmdldF8yMDA3ID0gdGFyZ2V0XzIwMDckYWVfdGFyZ2V0XzIwMDcsDQogICAgICAgICAgIHRhcmdldF8yMDA4ID0gdGFyZ2V0XzIwMDgkYWVfdGFyZ2V0XzIwMDgsDQogICAgICAgICAgIHRhcmdldF8yMDA5ID0gdGFyZ2V0XzIwMDkkYWVfdGFyZ2V0XzIwMDksDQogICAgICAgICAgIHRhcmdldF8yMDEwID0gdGFyZ2V0XzIwMTAkYWVfdGFyZ2V0XzIwMTAsDQogICAgICAgICAgIHRhcmdldF8yMDExID0gdGFyZ2V0XzIwMTEkYWVfdGFyZ2V0XzIwMTEsDQogICAgICAgICAgIHRhcmdldF8yMDEyID0gdGFyZ2V0XzIwMTIkYWVfdGFyZ2V0XzIwMTIsDQogICAgICAgICAgIHRhcmdldF8yMDEzID0gdGFyZ2V0XzIwMTMkYWVfdGFyZ2V0XzIwMTMsDQogICAgICAgICAgIHRhcmdldF8yMDE0ID0gdGFyZ2V0XzIwMTQkYWVfdGFyZ2V0XzIwMTQsDQogICAgICAgICAgIHRhcmdldF8yMDE1ID0gdGFyZ2V0XzIwMTUkYWVfdGFyZ2V0XzIwMTUsDQogICAgICAgICAgIHRhcmdldF8yMDE2ID0gdGFyZ2V0XzIwMTYkYWVfdGFyZ2V0XzIwMTYsDQogICAgICAgICAgIHRhcmdldF8yMDE3ID0gdGFyZ2V0XzIwMTckYWVfdGFyZ2V0XzIwMTcsDQogICAgICAgICAgIHRhcmdldF8yMDE4ID0gdGFyZ2V0XzIwMTgkYWVfdGFyZ2V0XzIwMTgsDQogICAgICAgICAgIHRhcmdldF8yMDE5ID0gdGFyZ2V0XzIwMTkkYWVfdGFyZ2V0XzIwMTksDQogICAgICAgICAgIHRhcmdldF8yMDIwID0gdGFyZ2V0XzIwMjAkYWVfdGFyZ2V0XzIwMjAsDQogICAgICAgICAgIHRhcmdldF8yMDIxID0gdGFyZ2V0XzIwMjEkYWVfdGFyZ2V0XzIwMjENCiAgICAgICAgICAgICAgICAgICkNCg0KZ2dwbG90KGRhdGEgPSBzY290bGFuZCkgKw0KICAgIGdlb21fc2YoYWVzKGZpbGwgPSBjaGFuZ2VfYWUpKSArDQogICAgc2NhbGVfZmlsbF92aXJpZGlzX2Mob3B0aW9uID0gInBsYXNtYSIpKw0KICBsYWJzKHRpdGxlID0gInBlcmNlbnQgY2hhbmdlIGluIEEmRSBkZXB0cyBtZWV0aW5nIHRoZSA0IGhvdXIgdGFyZ2V0IDIwMDcgLSAyMDE4IikNCiAgDQoNCmdncGxvdChkYXRhID0gc2NvdGxhbmQpICsNCiAgICBnZW9tX3NmKGFlcyhmaWxsID0gdGFyZ2V0XzIwMTgpKSArDQogICAgc2NhbGVfZmlsbF92aXJpZGlzX2Mob3B0aW9uID0gInBsYXNtYSIpKw0KICB0aGVtZV92b2lkKCkrDQogIGxhYnModGl0bGUgPSAiUGVyY2VudCBvZiBBJkUgZGVwdHMgbWFraW5nIHRoZSA0aHIgdGFyZ2V0IikNCmBgYA0KDQoNCmBgYHtyfQ0KZ2dwbG90KGRhdGEgPSBzY290bGFuZCkgKw0KZ2VvbV9zZihmaWxsID0gImdyZWVuIikrDQpnZ3JlcGVsOjpnZW9tX3RleHRfcmVwZWwoYWVzKHggPSBsYXQgLCB5ID0gbG9uZywgbGFiZWwgPSBwYXN0ZShIQkNvZGUsIEhCTmFtZSwgc2VwID0gIlxuIikpLCBtaW4uc2VnbWVudC5sZW5ndGggPSAwLjA1LHNpemUgPSAyLCBjb2xvciA9ICJibGFjayIsIGZvbnRmYWNlID0gImJvbGQiKSArDQogIHRoZW1lX3ZvaWQoKQ0KYGBgDQoNCg0KYGBge3J9DQoNCmxpYnJhcnkoc2YpDQoNCnNjb3RsYW5kX3NtYWxsZXIgPC0gc2NvdGxhbmQgJT4lICMgbWFrZSBhIHNtYWxsZXIgdmVyc2lvbiBmb3IgcGVyZm9ybWFuY2UgaXNzdWVzDQogIHN0X3NpbXBsaWZ5KFRSVUUsIGRUb2xlcmFuY2UgPSAyMDAwKQ0KI2ZpeGVzIHByb2JsZW1zIGNhdXNlZCBieSBhYm92ZSANCnNjb3RsYW5kX3NtYWxsZXIgPC0gc2Y6OnN0X2Nhc3Qoc2NvdGxhbmRfc21hbGxlciwgIk1VTFRJUE9MWUdPTiIpDQoNCg0KIyANCiMgICBmaWcgPC0gZ2dwbG90bHkoDQojICAgICBnZ3Bsb3Qoc2NvdGxhbmQpKw0KIyAgIGdlb21fc2YoYWVzKGZpbGwgPSBIQk5hbWUpKQ0KIyApDQojICAgZmlnDQoNCiAgDQogIHAgPC0gZ2dwbG90KHNjb3RsYW5kX3NtYWxsZXIpICsgDQogIGdlb21fc2YoYWVzKGZpbGwgPSBIQk5hbWUsIHRleHQgPSBwYXN0ZSgiPGI+IiwgSEJOYW1lLCAiPC9iPlxuIiwgSEJDb2RlKSkpKw0KICAgIHRoZW1lX3ZvaWQoKQ0KICBwICU+JQ0KICBnZ3Bsb3RseSh0b29sdGlwID0gInRleHQiKSAlPiUNCiAgc3R5bGUoaG92ZXJsYWJlbCA9IGxpc3QoYmdjb2xvciA9ICJ3aGl0ZSIpLCBob3Zlcm9uID0gImZpbGwiKQ0KICAgIA0KICANCmBgYA0KDQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQoNCmBgYHtyfQ0KY292aWRfYWdlX3NleCA8LSByZWFkX2NzdigicmF3X2RhdGEvY292aWRfcmF3X2RhdGEvaG9zcGl0YWxfYWRtaXNzaW9uc19oYl9hZ2VzZXhfMjAyMjAzMDIuY3N2IikNCg0KaGVhZChjb3ZpZF9hZ2Vfc2V4KQ0KYGBgDQoNCmBgYHtyfQ0KbGlicmFyeShsZWFmbGV0KQ0KDQpkYXRhKHF1YWtlcykNCg0KIyBTaG93IGZpcnN0IDIwIHJvd3MgZnJvbSB0aGUgYHF1YWtlc2AgZGF0YXNldA0KbGVhZmxldChkYXRhID0gcXVha2VzWzE6MjAsXSkgJT4lIGFkZFRpbGVzKCkgJT4lDQogIGFkZE1hcmtlcnMofmxvbmcsIH5sYXQsIHBvcHVwID0gfmFzLmNoYXJhY3RlcihtYWcpKQ0KYGBgDQoNCg==